certrev-api-contract
v2.8.7
Published
API contract types and schemas for CertRev verification engines. MVP is the source of truth.
Maintainers
Readme
@certrev/api-contract
API contract types and Zod schemas for CertRev verification engines.
The certrev-mvp repository is the SOURCE OF TRUTH for this contract.
Installation
# For MVP (workspace dependency)
pnpm add @certrev/api-contract
# For external engines (when published to npm)
npm install @certrev/api-contractUsage
Types (Compile-time)
import type {
VerificationJob,
TipTapDocument,
ClaimResult,
APAReference,
} from '@certrev/api-contract'
const job: VerificationJob = { ... }Schemas (Runtime Validation)
import {
VerificationJobSchema,
TipTapDocumentSchema,
CreateJobInputSchema,
} from '@certrev/api-contract'
// Validate incoming data
const result = VerificationJobSchema.safeParse(data)
if (!result.success) {
console.error('Invalid job:', result.error)
}Constants
import {
STAGE_LABELS,
ERROR_MESSAGES,
CONTRACT_VERSION,
} from '@certrev/api-contract'
// Show progress to users
const label = STAGE_LABELS[job.stage_name] // "Verifying critical claims"
// Show errors to users
const message = ERROR_MESSAGES[error.code] // "Rate limit exceeded..."Contract Version
Current version: 2.1.0
Check CONTRACT_VERSION constant for programmatic access.
For Engine Developers
Engines MUST:
- Poll
verification_jobstable for jobs withstatus = 'pending'AND matching engine - Update jobs with progress using
JobProgressUpdateschema - Complete jobs with
JobCompletionschema - Fail jobs with
JobFailureschema
See schemas.ts for exact shapes.
Engine Routing
Jobs are assigned to specific engines via the options.engine field. Each engine should poll only for jobs assigned to it:
-- cr-engine-v2 polls:
SELECT * FROM verification_jobs
WHERE status = 'pending'
AND options->>'engine' = 'cr-engine-v2'
ORDER BY created_at ASC
LIMIT 1
-- cr-engine-v3 polls:
SELECT * FROM verification_jobs
WHERE status = 'pending'
AND options->>'engine' = 'cr-engine-v3'
ORDER BY created_at ASC
LIMIT 1Available engines:
| Engine ID | Name | Description |
|-----------|------|-------------|
| cr-engine-v2 | CR Engine V2 | Stable version |
| cr-engine-v3 | CR Engine V3 (BMAD) | Latest with BMAD improvements |
Handling legacy jobs: Jobs created before engine routing (without options.engine) can be handled by any engine or ignored based on your deployment needs.
Footnote Mark Format
The MVP frontend TipTap editor expects footnotes as marks with this exact structure:
// In output_document nodes, add this mark to cited text:
{
type: 'footnote',
attrs: {
footnoteNumbers: [1, 2], // References supporting this claim
claimId: 'uuid' // Links to ClaimResult.id
}
}Example: A paragraph with a footnoted claim:
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Studies show this treatment is effective" },
{
"type": "text",
"text": " for patients",
"marks": [{
"type": "footnote",
"attrs": {
"footnoteNumbers": [1, 3],
"claimId": "claim-123"
}
}]
},
{ "type": "text", "text": "." }
]
}The frontend renders this as: "...effective for patients[1,3]."
Frontend support:
- TipTap
Footnoteextension insrc/lib/editor/tiptap-config.ts - Renders as
<sup data-footnote="true" class="footnote-marker">[1,3]</sup> - DOMPurify whitelist includes
suptag anddata-footnoteattribute
Breaking Changes
See CHANGELOG.md for version history.
What's breaking:
- Removing a field from output
- Changing a field's type
- Renaming a required field
- Adding a required input field
What's NOT breaking:
- Adding optional fields
- Adding new error codes
- Adding new claim types
