@superapp_men/pedagogical-data-exchange
v1.0.0
Published
Pedagogical data exchange package for SuperApp Partner Applications
Maintainers
Readme
@superapp_men/pedagogical-data-exchange
📚 Complete Guide to Pedagogical Data Exchange Package
📋 Table of Contents
- Overview
- Installation
- Quick Start
- Core Concepts
- API Reference
- Complete Examples
- Validation & Remediation
- Advanced Features
- Best Practices
🎯 Overview
This package enables Partner Applications to submit detailed student assessment data to SuperApp in a secure, structured, and pedagogically consistent manner.
What It Does
✅ Submit student test results and assessments
✅ Report partial or completed evaluations
✅ Support validation and remediation workflows
✅ Track learning progress and performance
✅ Provide rich analytics and insights
✅ Ensure compatibility with SuperApp's pedagogical model
Key Principle
Partner Applications submit facts, not decisions.
SuperApp retains full responsibility for:
- ✓ Skill validation
- ✓ Week unlocking
- ✓ Progression decisions
- ✓ Grade calculations
📦 Installation
npm install @superapp_men/pedagogical-data-exchangeOr with Yarn:
yarn add @superapp_men/pedagogical-data-exchangeOr with PNPM:
pnpm add @superapp_men/pedagogical-data-exchange🚀 Quick Start
30-Second Integration
import {
AssessmentSubmissionBuilder,
SkillResultBuilder,
QuestionResultBuilder,
SubmissionStatus,
QuestionType,
validateSubmission,
} from "@superapp_men/pedagogical-data-exchange";
// 1. Build a question
const question = new QuestionResultBuilder("MATH-Q1", QuestionType.VALIDATION)
.setResult(true)
.setAttempts(1)
.setAnsweredAt(new Date())
.setDuration(32)
.build();
// 2. Build a skill
const skill = new SkillResultBuilder("MATH-SK1")
.setStatus("Completed")
.addQuestion(question)
.build();
// 3. Build submission
const submission = new AssessmentSubmissionBuilder(
"STUDENT-ID",
SubmissionStatus.COMPLETED
)
.setProgressPercentage(100)
.setSourceApplication("MY_APP", "SESSION-ID")
.addSkill(skill)
.build();
// 4. Validate
const validation = validateSubmission(submission);
if (!validation.isValid) {
console.error("Errors:", validation.errors);
return;
}
// 5. Send to SuperApp
await sendToSuperApp(submission);🧩 Core Concepts
Data Structure
AssessmentSubmission
├── Student ID (studentIID)
├── Status (Partial/Completed/Abandoned)
├── Progress (percentage, last question, counts)
├── Skills[]
│ ├── Skill Code
│ ├── Skill Status (InProgress/Completed/Failed)
│ └── Questions[]
│ ├── Question Code
│ ├── Question Type (Validation/Remediation)
│ ├── Result (true/false)
│ ├── Attempts Count
│ ├── Duration
│ └── Answered At (timestamp)
├── Performance Summary (auto-calculated)
├── Pedagogical Insights (optional)
└── Metadata (source, session, device)Submission Statuses
| Status | When to Use | | ------------- | --------------------------------------- | | Partial | Student is still working; save progress | | Completed | Student finished all questions | | Abandoned | Student quit without finishing |
Question Types
| Type | Purpose | | --------------- | ---------------------------- | | Validation | Test skill mastery | | Remediation | Help after failed validation | | Diagnostic | Assess starting level | | Practice | Skill reinforcement |
📚 API Reference
1. AssessmentSubmissionBuilder
Create a complete submission:
new AssessmentSubmissionBuilder(studentIID: string, status: SubmissionStatus)Methods:
// Progress
.setProgressPercentage(percentage: number)
.setLastAnsweredQuestion(questionCode: string)
// Source
.setSourceApplication(code: string, sessionId: string, deviceType?: string)
// Assessment
.setAssessment(code: string, name?: string, weekNumber?: number)
// Skills
.addSkill(skill: SkillResult)
.addSkills(skills: SkillResult[])
// Performance
.setPerformanceSummary(summary: PerformanceSummary)
.setPedagogicalInsights(insights: PedagogicalInsights)
// Build
.build(): AssessmentSubmissionExample:
const submission = new AssessmentSubmissionBuilder(
"STU-001",
SubmissionStatus.COMPLETED
)
.setProgressPercentage(100)
.setSourceApplication("PARTNER_APP", "SESSION-123", "Mobile")
.setAssessment("MATH-W3", "Week 3 Math", 3)
.addSkill(skill)
.build();2. SkillResultBuilder
Create a skill with questions:
new SkillResultBuilder(skillCode: string)Methods:
// Status
.setStatus(status: 'InProgress' | 'Completed' | 'Failed')
.setName(name: string)
.setMasteryPercentage(percentage: number)
// Timing
.setTotalDuration(seconds: number)
.setStartedAt(timestamp: string | Date)
.setCompletedAt(timestamp: string | Date)
// Questions
.addQuestion(question: QuestionResult)
.addQuestions(questions: QuestionResult[])
// Build
.build(): SkillResultExample:
const skill = new SkillResultBuilder("MATH-W3-SK1")
.setStatus("Completed")
.setName("Addition and Subtraction")
.setMasteryPercentage(95)
.addQuestion(question1)
.addQuestion(question2)
.build();3. QuestionResultBuilder
Create a question result:
new QuestionResultBuilder(questionCode: string, questionType: QuestionType)Methods:
// Core
.setResult(result: boolean)
.setAttempts(count: number)
.setAnsweredAt(timestamp: string | Date)
.setDuration(seconds: number)
// Remediation
.setTriggeredBy(questionCode: string, round?: number)
.setValidationPassedAfterRemediation(passed: boolean)
// Additional
.setDifficulty(level: DifficultyLevel)
.setPoints(earned: number, max: number)
// Build
.build(): QuestionResultExample:
const question = new QuestionResultBuilder(
"MATH-W3-SK1-Q1",
QuestionType.VALIDATION
)
.setResult(true)
.setAttempts(1)
.setAnsweredAt(new Date())
.setDuration(32)
.build();4. Helper Functions
SubmissionHelpers
// Quick validation question
SubmissionHelpers.createValidationQuestion(
code: string,
result: boolean,
attempts?: number,
duration?: number
): QuestionResult
// Quick remediation question
SubmissionHelpers.createRemediationQuestion(
code: string,
triggeredBy: string,
result: boolean,
round?: number,
duration?: number
): QuestionResult
// Auto-calculate performance
SubmissionHelpers.calculatePerformanceSummary(
skills: SkillResult[]
): PerformanceSummary
// Auto-calculate progress
SubmissionHelpers.calculateProgress(
skills: SkillResult[],
totalExpectedQuestions?: number
): ProgressTrackingExamples:
// Create validation question quickly
const q1 = SubmissionHelpers.createValidationQuestion("Q1", true, 1, 30);
// Create remediation question quickly
const r1 = SubmissionHelpers.createRemediationQuestion(
"Q1-R1",
"Q1",
true,
1,
40
);
// Auto-calculate performance
const performance = SubmissionHelpers.calculatePerformanceSummary(skills);
// Auto-calculate progress
const progress = SubmissionHelpers.calculateProgress(skills, 20);5. Validation
validateSubmission(submission: AssessmentSubmission): ValidationResultReturns:
{
isValid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}Example:
const result = validateSubmission(submission);
if (!result.isValid) {
console.error("Validation failed!");
result.errors.forEach((error) => {
console.error(`[${error.code}] ${error.message}`);
});
return;
}
console.log("✅ Validation passed!");6. Utilities
import { PedagogicalUtils } from '@superapp_men/pedagogical-data-exchange';
// Calculate metrics
PedagogicalUtils.calculateAccuracy(skills): number
PedagogicalUtils.calculateSkillCompletionRate(skills): number
PedagogicalUtils.calculateTotalTimeSpent(skills): number
// Get questions
PedagogicalUtils.getValidationQuestions(skills): QuestionResult[]
PedagogicalUtils.getRemediationQuestions(skills): QuestionResult[]
// Analysis
PedagogicalUtils.generateSummary(submission): SummaryObject
PedagogicalUtils.exportToCSV(submission): string
PedagogicalUtils.formatDuration(seconds): string📖 Complete Examples
Example 1: Simple Completed Test
import {
AssessmentSubmissionBuilder,
SkillResultBuilder,
SubmissionHelpers,
SubmissionStatus,
DeviceType,
} from "@superapp_men/pedagogical-data-exchange";
// Build skill with 5 questions
const skill = new SkillResultBuilder("MATH-W1-SK1")
.setStatus("Completed")
.setName("Basic Addition")
.addQuestions([
SubmissionHelpers.createValidationQuestion("Q1", true, 1, 20),
SubmissionHelpers.createValidationQuestion("Q2", true, 1, 25),
SubmissionHelpers.createValidationQuestion("Q3", true, 1, 18),
SubmissionHelpers.createValidationQuestion("Q4", true, 1, 22),
SubmissionHelpers.createValidationQuestion("Q5", true, 1, 30),
])
.build();
// Build submission
const submission = new AssessmentSubmissionBuilder(
"STU-001",
SubmissionStatus.COMPLETED
)
.setProgressPercentage(100)
.setSourceApplication("PARTNER_APP", "SESSION-001", DeviceType.TABLET)
.setAssessment("MATH-W1", "Week 1 Assessment", 1)
.addSkill(skill)
.build();
// Validate and send
const validation = validateSubmission(submission);
if (validation.isValid) {
await sendToSuperApp(submission);
}Example 2: Partial Submission (Student Paused)
// Student completed 1 skill, partially completed another
const skill1 = new SkillResultBuilder("MATH-W2-SK1")
.setStatus("Completed")
.addQuestions([
SubmissionHelpers.createValidationQuestion("SK1-Q1", true, 1, 30),
SubmissionHelpers.createValidationQuestion("SK1-Q2", true, 1, 35),
])
.build();
const skill2 = new SkillResultBuilder("MATH-W2-SK2")
.setStatus("InProgress")
.addQuestions([
SubmissionHelpers.createValidationQuestion("SK2-Q1", true, 1, 40),
// Student stopped here
])
.build();
const submission = new AssessmentSubmissionBuilder(
"STU-002",
SubmissionStatus.PARTIAL
)
.setProgressPercentage(50)
.setLastAnsweredQuestion("SK2-Q1")
.setSourceApplication("PARTNER_APP", "SESSION-002")
.addSkills([skill1, skill2])
.build();
await sendToSuperApp(submission);Example 3: Failed → Remediation → Success
import {
QuestionResultBuilder,
QuestionType,
} from "@superapp_men/pedagogical-data-exchange";
// Complete remediation flow
const questions = [
// 1. Failed validation
new QuestionResultBuilder("MATH-Q1", QuestionType.VALIDATION)
.setResult(false)
.setAttempts(2)
.setAnsweredAt("2026-01-08T10:20:03Z")
.setDuration(51)
.build(),
// 2. Remediation
new QuestionResultBuilder("MATH-Q1-R1", QuestionType.REMEDIATION)
.setResult(true)
.setAttempts(1)
.setAnsweredAt("2026-01-08T10:22:40Z")
.setDuration(40)
.setTriggeredBy("MATH-Q1", 1)
.build(),
// 3. Retry validation (success!)
new QuestionResultBuilder("MATH-Q1", QuestionType.VALIDATION)
.setResult(true)
.setAttempts(3)
.setAnsweredAt("2026-01-08T10:24:05Z")
.setDuration(36)
.setValidationPassedAfterRemediation(true)
.build(),
];
const skill = new SkillResultBuilder("MATH-SK1")
.setStatus("Completed")
.addQuestions(questions)
.build();Example 4: With Auto-Calculated Performance
import { SubmissionHelpers } from "@superapp_men/pedagogical-data-exchange";
// Build skills
const skills = [skill1, skill2, skill3];
// Auto-calculate performance
const performance = SubmissionHelpers.calculatePerformanceSummary(skills);
// Build submission with performance
const submission = new AssessmentSubmissionBuilder(
"STU-003",
SubmissionStatus.COMPLETED
)
.setProgressPercentage(100)
.setSourceApplication("PARTNER_APP", "SESSION-003")
.setPerformanceSummary(performance)
.addSkills(skills)
.build();
await sendToSuperApp(submission);🔄 Validation & Remediation
The Flow
1. Validation Question (Test)
↓
Pass or Fail?
↓
┌─────┴─────┐
│ │
Pass Fail
│ │
│ ↓
│ 2. Remediation
│ (Learn)
│ ↓
│ 3. Retry Validation
│ │
└───────────┴──→ Skill CompleteImplementation
// Step 1: Failed validation
const failedValidation = new QuestionResultBuilder(
"MATH-W3-SK2-Q1",
QuestionType.VALIDATION
)
.setResult(false)
.setAttempts(2)
.setAnsweredAt("2026-01-08T10:20:03Z")
.setDuration(51)
.build();
// Step 2: Remediation
const remediation = new QuestionResultBuilder(
"MATH-W3-SK2-Q1-R1",
QuestionType.REMEDIATION
)
.setResult(true)
.setAttempts(1)
.setAnsweredAt("2026-01-08T10:22:40Z")
.setDuration(40)
.setTriggeredBy("MATH-W3-SK2-Q1", 1)
.build();
// Step 3: Successful retry
const successfulRetry = new QuestionResultBuilder(
"MATH-W3-SK2-Q1",
QuestionType.VALIDATION
)
.setResult(true)
.setAttempts(3)
.setAnsweredAt("2026-01-08T10:24:05Z")
.setDuration(36)
.setValidationPassedAfterRemediation(true)
.build();
// Add all to skill
const skill = new SkillResultBuilder("MATH-W3-SK2")
.setStatus("Completed")
.addQuestion(failedValidation)
.addQuestion(remediation)
.addQuestion(successfulRetry)
.build();⚡ Advanced Features
Performance Analytics
import { PedagogicalUtils } from "@superapp_men/pedagogical-data-exchange";
// Calculate metrics
const accuracy = PedagogicalUtils.calculateAccuracy(skills);
const completionRate = PedagogicalUtils.calculateSkillCompletionRate(skills);
const avgAttempts = PedagogicalUtils.calculateAverageAttempts(skills);
const totalTime = PedagogicalUtils.calculateTotalTimeSpent(skills);
console.log(`
Accuracy: ${accuracy.toFixed(1)}%
Completion: ${completionRate.toFixed(1)}%
Avg Attempts: ${avgAttempts.toFixed(2)}
Total Time: ${PedagogicalUtils.formatDuration(totalTime)}
`);Summary Generation
const summary = PedagogicalUtils.generateSummary(submission);
console.log(summary);
// {
// studentId: 'STU-123',
// totalSkills: 3,
// completedSkills: 2,
// totalQuestions: 15,
// correctAnswers: 12,
// accuracy: 80,
// totalTime: 840,
// averageAttempts: 1.5,
// remediationRate: 100
// }CSV Export
const csv = PedagogicalUtils.exportToCSV(submission);
// Save or send to server
fs.writeFileSync("results.csv", csv);Batch Submissions
// Create batch for multiple students
const submissions = [
createSubmissionForStudent("STU-001"),
createSubmissionForStudent("STU-002"),
createSubmissionForStudent("STU-003"),
];
const batch = PedagogicalUtils.createBatchSubmission(
submissions,
"PARTNER_APP"
);
await sendBatchToSuperApp(batch);✅ Best Practices
1. Always Validate
const validation = validateSubmission(submission);
if (!validation.isValid) {
logErrors(validation.errors);
return;
}2. Use Builders (Type Safe)
// ✅ Good
const question = new QuestionResultBuilder("Q1", QuestionType.VALIDATION)
.setResult(true)
.build();
// ❌ Bad
const question = {
questionCode: "Q1",
questionType: "Validation",
result: true,
};3. Use ISO 8601 Timestamps
// ✅ Good
.setAnsweredAt(new Date().toISOString())
.setAnsweredAt('2026-01-08T10:15:22Z')
// ❌ Bad
.setAnsweredAt('01/08/2026 10:15 AM')4. Track Durations
const startTime = Date.now();
// Student answers...
const duration = Math.round((Date.now() - startTime) / 1000);
questionBuilder.setDuration(duration);5. Use Helpers
// Quick question creation
const q = SubmissionHelpers.createValidationQuestion("Q1", true, 1, 30);6. Auto-Calculate Performance
const performance = SubmissionHelpers.calculatePerformanceSummary(skills);
builder.setPerformanceSummary(performance);7. Handle Partial Submissions
// Save progress when student pauses
if (studentPaused) {
const partial = builder
.setProgressPercentage(currentProgress)
.setLastAnsweredQuestion(lastQuestionCode)
.build();
await sendToSuperApp(partial);
}8. Link Remediation Properly
remediationBuilder.setTriggeredBy("VALIDATION-Q-CODE", roundNumber).build();🔒 What NOT to Include
Partner Apps should submit facts, not decisions:
❌ Don't Include:
- Skill validation decisions
- Week unlocking logic
- Progression decisions
- Final grades
- Next skill recommendations
✅ Do Include:
- Raw results (true/false)
- Attempt counts
- Time spent
- Answer details
- Interaction data
SuperApp decides everything pedagogical.
📘 TypeScript Support
Full TypeScript support:
import type {
AssessmentSubmission,
SkillResult,
QuestionResult,
SubmissionStatus,
QuestionType,
ValidationResult,
SubmissionResponse,
} from "@superapp_men/pedagogical-data-exchange";🔍 Validation Rules
The validator checks:
✅ Required fields presence
✅ Correct data types
✅ Value ranges (0-100 for percentages)
✅ Logical consistency
✅ Remediation flow correctness
✅ ISO 8601 timestamps
✅ No duplicates
📊 SuperApp Response
After submission:
{
submissionId: string;
accepted: boolean;
processedAt: string;
validation: {
isValid: boolean;
errors?: ValidationError[];
};
processingResults?: {
validatedSkills?: string[];
unlockedSkills?: string[];
weekProgression?: { ... };
achievementsEarned?: string[];
pointsEarned?: number;
};
recommendations?: {
nextSkills?: string[];
remediationRequired?: string[];
};
}Handle Response
const response = await sendToSuperApp(submission);
if (response.accepted) {
console.log("✅ Accepted!");
if (response.processingResults?.weekProgression?.weekUnlocked) {
showNotification("New week unlocked!");
}
if (response.processingResults?.achievementsEarned) {
showAchievements(response.processingResults.achievementsEarned);
}
}🆘 Support
- Email: [email protected]
📄 License
MIT
Ready to integrate? Install and start submitting! 📚✨
