npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@superapp_men/pedagogical-data-exchange

v1.0.0

Published

Pedagogical data exchange package for SuperApp Partner Applications

Readme

@superapp_men/pedagogical-data-exchange

📚 Complete Guide to Pedagogical Data Exchange Package

📋 Table of Contents

  1. Overview
  2. Installation
  3. Quick Start
  4. Core Concepts
  5. API Reference
  6. Complete Examples
  7. Validation & Remediation
  8. Advanced Features
  9. 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-exchange

Or with Yarn:

yarn add @superapp_men/pedagogical-data-exchange

Or 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(): AssessmentSubmission

Example:

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(): SkillResult

Example:

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(): QuestionResult

Example:

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
): ProgressTracking

Examples:

// 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): ValidationResult

Returns:

{
  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 Complete

Implementation

// 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


📄 License

MIT


Ready to integrate? Install and start submitting! 📚✨