{"_id":"@3halves-labs/score-interactions-core","name":"@3halves-labs/score-interactions-core","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@3halves-labs/score-interactions-core","version":"0.1.0","description":"Shared, zero-dependency contract for loyalty interactions (surveys, polls, trivia, quizzes) — types + JSON schema + scoring","license":"MIT","keywords":["loyalty","survey","poll","trivia","quiz","gamification","schema","typescript"],"main":"dist/index.cjs.js","module":"dist/index.esm.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"sideEffects":false,"scripts":{"build":"tsup","clean":"rimraf dist","dev":"tsup --watch","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build","test":"vitest run","test:watch":"vitest","release":"../scripts/release-sdk.sh interactions-core interactions-core","release:patch":"../scripts/release-sdk.sh interactions-core interactions-core patch","release:minor":"../scripts/release-sdk.sh interactions-core interactions-core minor","release:major":"../scripts/release-sdk.sh interactions-core interactions-core major"},"devDependencies":{"rimraf":"^5.0.5","tsup":"^8.0.1","typescript":"^5.3.3","vitest":"^2.1.9"},"publishConfig":{"access":"public"},"_id":"@3halves-labs/score-interactions-core@0.1.0","gitHead":"385d6459aff08fa4032d9e3ea2ef06fffb2cbb08","_nodeVersion":"18.20.4","_npmVersion":"10.7.0","dist":{"integrity":"sha512-UBp5Rd4HG8M1VK3+KiHRq0j8QhybWQqcOuIuFuBhrpO+VNXoq4yAWLxTmbUMs2SiGq4GviHubC6qu5hm7g4bGA==","shasum":"c8e4aaad36ef2de1146e17d0690282f8053d2b7e","tarball":"https://registry.npmjs.org/@3halves-labs/score-interactions-core/-/score-interactions-core-0.1.0.tgz","fileCount":8,"unpackedSize":67408,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEGjjvAWzMnM+kRBiRwuGlx4gUdhvfQEzF0xbMTp6CGvAiB/9yaUxvUEf8w1uFUF+zv++TpNbOoxDdv+HuQGpgIZzA=="}]},"_npmUser":{"name":"3halves-labs","email":"info@3halves-labs.com"},"directories":{},"maintainers":[{"name":"3halves-labs","email":"info@3halves-labs.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/score-interactions-core_0.1.0_1787077687257_0.6649470390098553"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T18:28:07.121Z","0.1.0":"2026-08-18T18:28:07.463Z","modified":"2026-08-18T18:28:07.644Z"},"maintainers":[{"name":"3halves-labs","email":"info@3halves-labs.com"}],"description":"Shared, zero-dependency contract for loyalty interactions (surveys, polls, trivia, quizzes) — types + JSON schema + scoring","keywords":["loyalty","survey","poll","trivia","quiz","gamification","schema","typescript"],"license":"MIT","readme":"# @3halves-labs/score-interactions-core\n\nThe **shared, zero-dependency contract** for loyalty *interactions* — surveys, polls, trivia and quizzes. One primitive (`InteractionDefinition`) covers all of them; they differ only by `type`, per-question `graded`/`points`/`timeLimit`, and `scoringMode`.\n\nThis package is the single source of truth for the **schema** and the **scoring**, imported by every surface so they can't drift:\n\n- **Odoo** (`score.game*`) stores a definition that validates against `interactionSchema`.\n- **Middleware** serves definitions and **grades responses server-side** with `gradeInteraction` (never trusts a client score).\n- **Admin authoring** (survey-builder-pro, folded in) authors against the same types.\n- **Embeddable widget** renders the definition and previews scoring with the same `gradeInteraction`.\n\nPart of epic **#304** / ticket **#305**. See `docs/implementation-plans/interactions-surveys-polls-trivia.md`.\n\n## Install\n\n```bash\nnpm install @3halves-labs/score-interactions-core\n```\n\n## Use\n\n```ts\nimport {\n  gradeInteraction,\n  interactionSchema,\n  INTERACTION_SCHEMA_VERSION,\n  type InteractionDefinition,\n  type Answers,\n} from '@3halves-labs/score-interactions-core';\n\nconst def: InteractionDefinition = {\n  schemaVersion: INTERACTION_SCHEMA_VERSION,\n  id: 'rapid-fire-r12',\n  type: 'trivia',\n  title: 'Rapid Fire Trivia',\n  status: 'live',\n  completionPoints: 10,\n  scoringMode: 'both',\n  bonusAllCorrect: 50,\n  maxAttempts: 1,\n  showCorrectAnswers: true,\n  randomizeQuestions: true,\n  onePerFan: true,\n  questions: [\n    {\n      id: 'q1', type: 'multiple_choice', prompt: 'Who won?', required: true,\n      points: 10, graded: true, timeLimit: 15,\n      options: [\n        { id: 'a', label: 'Leinster', correct: true },\n        { id: 'b', label: 'Munster', correct: false },\n      ],\n    },\n  ],\n};\n\nconst answers: Answers = { q1: 'a' };\nconst result = gradeInteraction(def, answers);\n// → { total, questionPoints, completionPoints, bonusPoints, results: [...], missingRequired: [] }\n```\n\n## Exports\n\n| Export | What |\n| --- | --- |\n| `InteractionDefinition`, `InteractionQuestion`, `InteractionOption` | the definition types |\n| `InteractionType`, `QuestionType`, `ScoringMode`, `InteractionStatus` | enums |\n| `QUESTION_TYPES` | per-question-type metadata (label / gradable / hasOptions) for authoring UIs |\n| `interactionSchema` | draft-07 JSON Schema for the definition (middleware/Odoo validation) |\n| `gradeInteraction(def, answers)` | pure scoring — the server authority; also drives preview/test-mode |\n| `INTERACTION_SCHEMA_VERSION` | contract version stamped on every definition |\n\nZero runtime dependencies. Published from `main` via `npm run release:*`.\n","readmeFilename":"README.md","_rev":"1-040e4b4081a4261a536b6a428bd7153f"}