Перейти к содержимому
getnextpdf.com

Enterprise редакция

Compliance — глубокий справочник

Модуль Compliance направляет готовый PDF во внешний валидационный sidecar и возвращает один нормализованный результат. ComplianceGateway определяет ответственный sidecar по ComplianceProfile, применяет политику доступности fail-closed и оборачивает каждый вердикт инструмента в ExternalValidationResult. Поставляются мосты для veraPDF (PDF/A, PDF/UA, PDF 2.0 Arlington), EU DSS (уровни PAdES), объединённого sidecar Mustang/KoSIT (ZUGFeRD, Factur-X, EN 16931) и отдельного демона KoSIT. Модуль также предоставляет штамповку готовности AiReadyCertifier и раннер для официального набора тестов KoSIT XRechnung.

Эта возможность поставляется в NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без этого права не загружает классы возможности. Сравнить редакции и получить лицензию.

Поверхность Compliance/Evidence лицензируется возможностью enterprise.compliance.evidence. Отсутствующее или истёкшее право отказывает в функции; оно не понижает поведение молча.

УровеньПоверхность Compliance
CoreВнутрипроцессные проверки байтового потока и грамматики; без делегирования внешнему sidecar.
ProВнутрипроцессная проверка EN 16931 / Factur-X / ZUGFeRD; без внешнего sidecar.
EnterpriseШлюз внешних валидаторов (этот модуль) с единым результатом и политикой fail-closed.

Внутрипроцессный валидатор электронных счетов Pro и внешний sidecar ZUGFeRD в Enterprise — разные поверхности. Шлюз внешних валидаторов поставляется только в пакете nextpdf/enterprise.

Окно терминала
composer require nextpdf/enterprise:^3
СимволПараметрыПоведение по умолчаниюВозвращаетВозбуждает или завершается сПримечания
ComplianceGateway::__constructlist<ExternalValidator> $validators, LoggerInterface $logger, bool $optional = falseИндексирует валидаторы по имени инструментаНеобязательный режим понижает проверку доступности до только предупреждения
ComplianceGateway::validatestring $pdfContent, ComplianceProfile $profile, array $options = []Определяет валидатор по ComplianceProfile::toolName(), проверяет доступность, делегирует?ExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (для инструмента не зарегистрирован валидатор)Возвращает null только в необязательном режиме при недоступном sidecar
ComplianceGateway::validateAllProfilesstring $pdfContent, string $toolNameПроверяет каждый профиль, сопоставленный с инструментомlist<ExternalValidationResult>Как у validate()Пропускает результаты null (необязательный режим)
ComplianceGateway::healthCheckОпрашивает конечную точку здоровья каждого зарегистрированного sidecararray<string, bool>Сообщает о достижимости; документ не проверяет
ComplianceGateway::buildComplianceMatrix (статический)list<ExternalValidationResult> $results, string $commitShaСводит результаты в матрицу с версией схемыarray<string, mixed>Версия схемы 1.0; фиксирует вывод инструмента, ничего не утверждает
ComplianceProfile (перечисление)15 строковых вариантовСопоставляет каждый профиль стандартной метке и инструментуstandardReference(): string, toolName(): string
ExternalValidator (интерфейс)Контракт моста sidecar поверх PSR-18validate() возбуждает ComplianceSidecarUnavailableException при сбое транспортаgetToolName(), isAvailable(), validate()
VeraPdfValidator::validateСигнатура интерфейсаMultipart POST к REST-sidecar veraPDF; разбор JSON-отчётаExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль)PDF/A, PDF/UA, Arlington; разбирает только JSON, никогда XML
DssValidator::validateСигнатура интерфейсаBase64 JSON POST к REST-sidecar EU DSSExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль)PAdES B-B до B-LTA; конструктор отклоняет тайм-ауты меньше одной секунды
ZugferdExternalValidator::validateСигнатура интерфейсаMultipart POST к объединённому sidecar Mustang/KoSITExternalValidationResultComplianceSidecarUnavailableException (в том числе при разомкнутом circuit breaker); InvalidArgumentException (неподдерживаемый профиль)ZUGFeRD 2.4, Factur-X 1.08, EN 16931; опциональный внедрённый circuit breaker
KoSitValidator::validateСигнатура интерфейсаСырой XML POST к отдельному демону KoSITExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль)Только EN 16931; разбирает отчёт Schematron SVRL по принципу fail-closed
ExternalValidationResultНеизменяемый объект-значениеНормализованный вердикт инструментаpasses(), fails(), nonConformanceCount(), toComplianceMatrix()
NonConformanceНеизменяемый объект-значениеОтдельное несоответствие с идентификатором правила, пунктом, уровнем серьёзности, расположениемtoArray()
ComplianceSidecarUnavailableExceptionstring $toolName, string $endpoint, int $code = 0, ?Throwable $previous = nullСигнал недоступности sidecar по принципу fail-closedПубличные readonly toolName и endpoint
AiReadyCertifier::certifystring $pdfBytesОценивает три критерия готовности; штампует XMP-происхождениеarray{0: AiReadyCertification, 1: string}InvalidArgumentException (для штамповки нужна классическая таблица перекрёстных ссылок)Второй элемент равен входным данным, когда уровень равен not_certified
AiReadyCertificationНеизменяемый объект-значениеОценка готовности с уровнем, числом критериев, проблемами, хешем источникаВнутренняя метка готовности, а не сертификация по стандарту
XRechnungTestSuiteRunner::__constructstring $suitePath, ExternalValidator $validator, bool $useCuratedNegativeFallback = trueОпределяет каталог распакованного набораInvalidArgumentException (каталог не существует)Нацелен на официальный набор тестов KoSIT XRechnung
XRechnungTestSuiteRunner::runbool $stopOnFirstFailure = falseПроверяет каждый экземпляр набора через мостXRechnungTestSuiteResultXRechnungTestSuiteException (валидатор недоступен; нет XML-файлов)Также isAvailable(), getSuitePath(), discoverTestFiles()
XRechnungTestSuiteResultНеизменяемый объект-значениеАгрегированный итог набораallPassed(), totalCount(), getFailures(), getErrors(), toSummary()
XRechnungTestCaseResultНеизменяемый объект-значениеИтог по отдельному случаюpassed(), hasError(), getFilename()
XRechnungTestSuiteExceptionСтатические конструкторыСигнал сбоя во время выполнения набораselfvalidatorUnavailable(), noTestFilesFound(string $suitePath)
namespace NextPDF\Enterprise\Compliance;
final class ComplianceGateway
{
/** @param list<ExternalValidator> $validators */
public function __construct(
array $validators,
private readonly LoggerInterface $logger,
private readonly bool $optional = false,
);
/** @param array<string, mixed> $options */
public function validate(
string $pdfContent,
ComplianceProfile $profile,
array $options = [],
): ?ExternalValidationResult;
/** @return list<ExternalValidationResult> */
public function validateAllProfiles(string $pdfContent, string $toolName): array;
/** @return array<string, bool> */
public function healthCheck(): array;
/**
* @param list<ExternalValidationResult> $results
* @return array<string, mixed>
*/
public static function buildComplianceMatrix(array $results, string $commitSha): array;
}
interface ExternalValidator
{
public function getToolName(): string;
public function isAvailable(): bool;
/** @param array<string, mixed> $options */
public function validate(
string $pdfContent,
ComplianceProfile $profile,
array $options = [],
): ExternalValidationResult;
}
enum ComplianceProfile: string
{
case PdfA1b = 'pdfa-1b';
// PdfA2b, PdfA3b, PdfA4, PdfA4f, PdfUa1, PdfUa2, Pdf20Arlington,
// PadesBasic, PadesTimestamp, PadesLongTerm, PadesArchive,
// Zugferd24, FacturX108, En16931
public function standardReference(): string;
public function toolName(): string;
}
final class AiReadyCertifier
{
/** @return array{0: AiReadyCertification, 1: string} Tuple of [certification, stamped PDF bytes] */
public function certify(string $pdfBytes): array;
}

ComplianceGateway::validate() разрешает зарегистрированный ExternalValidator, чей getToolName() совпадает с ComplianceProfile::toolName(), проверяет isAvailable(), делегирует и возвращает нормализованный ExternalValidationResult. Внешне наблюдаемые правила:

  • Поведение fail-closed по умолчанию. Если разрешённый sidecar недоступен и необязательный режим выключен, вызов возбуждает ComplianceSidecarUnavailableException. Документ не проверяется; он никогда не считается прошедшим.
  • Необязательный режим. Создание шлюза с optional: true (операторы подключают это через переменную окружения NEXTPDF_COMPLIANCE_OPTIONAL) понижает недоступный sidecar до залогированного предупреждения и возврата null. Вызывающие должны трактовать null как «не проверено». Необязательный режим охватывает только предварительную проверку доступности; сбой транспорта во время самого вызова проверки возбуждает ComplianceSidecarUnavailableException в обоих режимах.
  • Неизвестный профиль. Профиль без зарегистрированного валидатора возбуждает InvalidArgumentException; он никогда не проходит молча.
  • Семантика прохождения. ExternalValidationResult::passes() требует, чтобы conformant было истинным и число несоответствий было нулевым. Каждый результат несёт профиль, имя и версию инструмента, число утверждений, найденные проблемы, SHA-256 проверенных байтов, метку времени UTC и длительность вызова.
  • Матрица — это запись, а не утверждение. buildComplianceMatrix() — статический редуктор, производящий структуру с версией схемы, версиями инструментов и commit SHA для прослеживаемости. Он фиксирует вывод инструмента; он ничего не утверждает.
  • Поток данных. Полный байтовый поток PDF передаётся настроенному sidecar по клиенту PSR-18. Каждая проверка логируется через PSR-3 с профилем, инструментом, результатом pass/fail, числом утверждений и длительностью.

Маршрутизация «профиль → инструмент», как возвращают ComplianceProfile::standardReference() и ::toolName():

Варианты профиляСсылка на стандартИнструмент
pdfa-1b, pdfa-2b, pdfa-3b, pdfa-4, pdfa-4fISO 19005-1/-2/-3/-4 (уровень B; уровень F для 4f)veraPDF
pdfua-1, pdfua-2ISO 14289-1:2014, ISO 14289-2:2024veraPDF
pdf20-arlingtonISO 32000-2:2020 (модель Arlington)veraPDF
pades-b-b, pades-b-t, pades-b-lt, pades-b-ltaETSI EN 319 142-1 B-B до B-LTAEU DSS
zugferd-2.4, factur-x-1.08, en-16931ZUGFeRD 2.4 / Factur-X 1.08 / EN 16931-1:2017Mustang/KoSIT

AiReadyCertifier::certify() оценивает три критерия: наличие структурной подписи, здоровье LTV и отсутствие шифрования. Три пройденных критерия дают уровень certified; один или два — partial; ноль — not_certified. При certified или partial добавляется инкрементное обновление, несущее XMP-поток происхождения и переопределение Catalog; исходные байты никогда не изменяются. Уровень «certified» — это внутренняя метка готовности NextPDF, а не сертификация по стандарту.

VeraPdfValidator разбирает только JSON-ответы sidecar (без XML; по построению свободен от XXE). KoSitValidator разбирает XML-отчёт SVRL демона с отклонением объявлений DOCTYPE и отключённым сетевым доступом и трактует неразбираемый отчёт как сбой вызова.

  • Тайм-аут sidecar или ошибка транспорта проявляется как ComplianceSidecarUnavailableException от моста; применяется поведение fail-closed по умолчанию.
  • Ответ sidecar, отличный от 200, даёт неуспешный результат с проблемой, специфичной для инструмента (например, VERAPDF-HTTP-ERROR); это никогда не прохождение соответствия.
  • Некорректное тело JSON или XML от sidecar — это сбой проверки вызова, а не прохождение соответствия.
  • Результаты EU DSS без подписей завершаются неуспехом с DSS-NO-SIGNATURES. Индикация, отличная от TOTAL_PASSED, завершается неуспехом с DSS-SIG-INVALID. Уровень подписи ниже ожидаемого базового завершается неуспехом с DSS-LEVEL-MISMATCH.
  • DssValidator публикует свой бюджет тайм-аута на каждый запрос через заголовок X-NextPDF-Timeout-Seconds; клиент PSR-18 интегратора должен его соблюдать, чтобы зависший sidecar не мог неограниченно блокировать вызывающий поток.
  • ZugferdExternalValidator при желании направляет вызовы sidecar через внедрённый circuit breaker; разомкнутый breaker отображается в ComplianceSidecarUnavailableException (fail-fast, по-прежнему fail-closed). По умолчанию используется breaker без действия.
  • KoSitValidator::isAvailable() принимает HTTP 200 и 405 от проверки здоровья демона; исправный демон отвечает на GET кодом 405.
  • Штамповка AiReadyCertifier завершается fail-closed с InvalidArgumentException, когда в исходном документе нет классической таблицы перекрёстных ссылок (например, потоки перекрёстных ссылок).
  • XRechnungTestSuiteRunner::run() отказывается запускаться, когда валидатор недоступен или набор не содержит XML-файлов; при включённом useCuratedNegativeFallback он подставляет курируемый негативный корпус, если набор не поставляет некорректных экземпляров.

Этот модуль не выполняет подписания и не хранит ключи. Политика алгоритмов в режиме FIPS управляется модулями Security и Signature. Соответствие подписи делегируется EU DSS, который выносит собственное решение.

Шлюз делегирует вердикт о соответствии внешнему инструменту; конструкция отражает собственную границу стандартов: соответствие определяется относительно требований, а не утверждается производителем.

ПоведениеСсылка
Обязанность соответствующего обработчика; соответствие определяется относительно стандартаISO 19005-4:2020 §5.2
Требования к файлу PDF/A-4 против самоутверждения производителяISO 19005-4:2020 §6.6.4
Соответствие PDF/UA-2 — это свойство файлаISO 14289-2:2024 §6
Уровни базовых подписей PAdESETSI EN 319 142-1 §5.4.3

Вердикт выносит внешний инструмент. NextPDF не имеет сертификации и не предоставляет её; поддержка профиля не является соответствием ему. Результаты проверки — это технические записи проверки структуры для справки, а не юридическое заключение; обратитесь в вашу команду по соответствию, чтобы оценить нормативную достаточность.

  • Оператор размещает и эксплуатирует sidecar-ы, фиксирует их версии, ограничивает их сетевую досягаемость, проверяет их TLS и контролирует окружение, включающее необязательный режим. Конечные точки sidecar — это граница доверия; средства контроля резидентности и хранения для документов, результатов и логов — ответственность оператора.
  • Вывод buildComplianceMatrix() предназначен для прослеживаемости в CI: зафиксируйте commit SHA и архивируйте матрицу рядом с артефактами сборки.
  • Раннер XRechnung ожидает официальный набор тестов, распакованный в локальный каталог; сообщение его конструктора называет публичный источник загрузки.
  • Внутренние детали механизма остаются во внутренней документации репозитория исходного кода и выходят за рамки этого руководства.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов руководств по эксплуатации и префиксы тикетов выходят за рамки.