octopos-ve-documents
Venezuelan identity documents (cédula, RIF, passport) for the octoPOS ecosystem: validation, mod-11 check digit, formatting, input masks and per-type placeholder examples. Zero runtime dependencies, dual ESM + CJS, TypeScript types included.
This package is the cross-repo single source of truth for the octoPOS Venezuelan identity-document standard (owner ruling 2026-07-16). The octoPOS repos (admin, pos, platform, web) consume it through thin per-repo shims.
The standard
- Cédula (person identity):
V|E+ 6–8 digits, stored zero-padded to 8; displayV-01234567. 9 digits is NEVER a cédula. - RIF (fiscal tax id):
V E J P G C+ 9 digits (8 body + 1 final digit); displayJ-12345678-9. Validation is format and length only (owner ruling 2026-07-18): SENIAT never officially published the check-digit algorithm and legitimately issued RIFs exist that do not match the public variant, so the mod-11 arithmetic (rifCheckDigit, prefix values{V:1,E:2,J:3,C:3,P:4,G:5}×4 + body weights[3,2,7,6,5,4,3,2], digit = 11 − (sum mod 11), → 0 when ≥ 10) is exposed as an informational utility — used e.g. to generate realistic placeholder examples — never as a write gate. Document legitimacy is verified by human review of the RIF certificate. - Passport (person identity, type P):
^[A-Z0-9]{5,15}$— person contexts only, never a fiscal tax number.
Storage and API contracts always carry the split pair (fiscal taxType+taxNumber, person idDocumentType+idDocument); the composed dashed string is display-only.
Install
npm install octopos-ve-documents
API
Split-pair (type letter + digits)
import { classifyTaxId, formatTaxId, isValidTaxId, rifCheckDigit } from "octopos-ve-documents";
classifyTaxId("V-1234567"); // { type: "V", number: "01234567", kind: "cedula" }
classifyTaxId("123456784"); // { type: "J", number: "123456784", kind: "rif" }
isValidTaxId("J-12345678-4"); // true (structure/length only)
formatTaxId("J", "123456784"); // "J-12345678-4"
rifCheckDigit("J", "123456780"); // 4 — informational mod-11 utility, never a gate
Composed-string (parse/compose canonical J-12345678-9 / V-01234567)
import { composeTaxId, composeTaxIdStrict, parseTaxId, validateRif } from "octopos-ve-documents";
parseTaxId("J-12345678-4"); // { type: "J", number: "123456784" } — structure-only
parseTaxId("J-12345678-9", { requireCheckDigit: true }); // null — opt-in mod-11 screening (informational)
composeTaxId("V", "1234567"); // "V-01234567" (loose: null on bad parts, never throws)
composeTaxIdStrict("J", "123456784"); // "J-12345678-4" (throws on structural problems only)
validateRif("J-12345678-4"); // true (format/length)
Input metadata (placeholders & masks)
import { documentInputRules, sanitizeDocumentInput, taxIdExample } from "octopos-ve-documents";
taxIdExample("V", "person"); // "12345678"
taxIdExample("P", "person"); // "AB123456"
taxIdExample("J", "fiscal"); // "301420608" — check digit computed, valid by construction
documentInputRules("P", "person"); // { alphanumeric: true, maxLength: 15, inputMode: "text" }
sanitizeDocumentInput("V", "12.345.678", "person"); // "12345678"
Testing
The suite pins the canonical cross-repo mod-11 vectors for the informational rifCheckDigit utility — matching: V-12345678-1 E-12345678-8 J-12345678-4 C-12345678-4 P-12345678-0 G-12345678-7 J-30142060-8; non-matching: V-12345678-9 E-12345678-0 J-12345678-9 C-12345678-5 P-12345678-1 G-12345678-1. (Validation gates accept both sets — they check format/length only.)
npm test
License
MIT