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.
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»composer require nextpdf/enterprise:^3| Символ | Параметры | Поведение по умолчанию | Возвращает | Возбуждает или завершается с | Примечания |
|---|---|---|---|---|---|
ComplianceGateway::__construct | list<ExternalValidator> $validators, LoggerInterface $logger, bool $optional = false | Индексирует валидаторы по имени инструмента | — | — | Необязательный режим понижает проверку доступности до только предупреждения |
ComplianceGateway::validate | string $pdfContent, ComplianceProfile $profile, array $options = [] | Определяет валидатор по ComplianceProfile::toolName(), проверяет доступность, делегирует | ?ExternalValidationResult | ComplianceSidecarUnavailableException; InvalidArgumentException (для инструмента не зарегистрирован валидатор) | Возвращает null только в необязательном режиме при недоступном sidecar |
ComplianceGateway::validateAllProfiles | string $pdfContent, string $toolName | Проверяет каждый профиль, сопоставленный с инструментом | list<ExternalValidationResult> | Как у validate() | Пропускает результаты null (необязательный режим) |
ComplianceGateway::healthCheck | — | Опрашивает конечную точку здоровья каждого зарегистрированного sidecar | array<string, bool> | — | Сообщает о достижимости; документ не проверяет |
ComplianceGateway::buildComplianceMatrix (статический) | list<ExternalValidationResult> $results, string $commitSha | Сводит результаты в матрицу с версией схемы | array<string, mixed> | — | Версия схемы 1.0; фиксирует вывод инструмента, ничего не утверждает |
ComplianceProfile (перечисление) | 15 строковых вариантов | Сопоставляет каждый профиль стандартной метке и инструменту | — | — | standardReference(): string, toolName(): string |
ExternalValidator (интерфейс) | — | Контракт моста sidecar поверх PSR-18 | — | validate() возбуждает ComplianceSidecarUnavailableException при сбое транспорта | getToolName(), isAvailable(), validate() |
VeraPdfValidator::validate | Сигнатура интерфейса | Multipart POST к REST-sidecar veraPDF; разбор JSON-отчёта | ExternalValidationResult | ComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль) | PDF/A, PDF/UA, Arlington; разбирает только JSON, никогда XML |
DssValidator::validate | Сигнатура интерфейса | Base64 JSON POST к REST-sidecar EU DSS | ExternalValidationResult | ComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль) | PAdES B-B до B-LTA; конструктор отклоняет тайм-ауты меньше одной секунды |
ZugferdExternalValidator::validate | Сигнатура интерфейса | Multipart POST к объединённому sidecar Mustang/KoSIT | ExternalValidationResult | ComplianceSidecarUnavailableException (в том числе при разомкнутом circuit breaker); InvalidArgumentException (неподдерживаемый профиль) | ZUGFeRD 2.4, Factur-X 1.08, EN 16931; опциональный внедрённый circuit breaker |
KoSitValidator::validate | Сигнатура интерфейса | Сырой XML POST к отдельному демону KoSIT | ExternalValidationResult | ComplianceSidecarUnavailableException; InvalidArgumentException (неподдерживаемый профиль) | Только EN 16931; разбирает отчёт Schematron SVRL по принципу fail-closed |
ExternalValidationResult | Неизменяемый объект-значение | Нормализованный вердикт инструмента | — | — | passes(), fails(), nonConformanceCount(), toComplianceMatrix() |
NonConformance | Неизменяемый объект-значение | Отдельное несоответствие с идентификатором правила, пунктом, уровнем серьёзности, расположением | — | — | toArray() |
ComplianceSidecarUnavailableException | string $toolName, string $endpoint, int $code = 0, ?Throwable $previous = null | Сигнал недоступности sidecar по принципу fail-closed | — | — | Публичные readonly toolName и endpoint |
AiReadyCertifier::certify | string $pdfBytes | Оценивает три критерия готовности; штампует XMP-происхождение | array{0: AiReadyCertification, 1: string} | InvalidArgumentException (для штамповки нужна классическая таблица перекрёстных ссылок) | Второй элемент равен входным данным, когда уровень равен not_certified |
AiReadyCertification | Неизменяемый объект-значение | Оценка готовности с уровнем, числом критериев, проблемами, хешем источника | — | — | Внутренняя метка готовности, а не сертификация по стандарту |
XRechnungTestSuiteRunner::__construct | string $suitePath, ExternalValidator $validator, bool $useCuratedNegativeFallback = true | Определяет каталог распакованного набора | — | InvalidArgumentException (каталог не существует) | Нацелен на официальный набор тестов KoSIT XRechnung |
XRechnungTestSuiteRunner::run | bool $stopOnFirstFailure = false | Проверяет каждый экземпляр набора через мост | XRechnungTestSuiteResult | XRechnungTestSuiteException (валидатор недоступен; нет XML-файлов) | Также isAvailable(), getSuitePath(), discoverTestFiles() |
XRechnungTestSuiteResult | Неизменяемый объект-значение | Агрегированный итог набора | — | — | allPassed(), totalCount(), getFailures(), getErrors(), toSummary() |
XRechnungTestCaseResult | Неизменяемый объект-значение | Итог по отдельному случаю | — | — | passed(), hasError(), getFilename() |
XRechnungTestSuiteException | Статические конструкторы | Сигнал сбоя во время выполнения набора | self | — | validatorUnavailable(), 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-4f | ISO 19005-1/-2/-3/-4 (уровень B; уровень F для 4f) | veraPDF |
pdfua-1, pdfua-2 | ISO 14289-1:2014, ISO 14289-2:2024 | veraPDF |
pdf20-arlington | ISO 32000-2:2020 (модель Arlington) | veraPDF |
pades-b-b, pades-b-t, pades-b-lt, pades-b-lta | ETSI EN 319 142-1 B-B до B-LTA | EU DSS |
zugferd-2.4, factur-x-1.08, en-16931 | ZUGFeRD 2.4 / Factur-X 1.08 / EN 16931-1:2017 | Mustang/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
Заголовок раздела «Поведение в режиме FIPS»Этот модуль не выполняет подписания и не хранит ключи. Политика алгоритмов в режиме 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 |
| Уровни базовых подписей PAdES | ETSI EN 319 142-1 §5.4.3 |
Вердикт выносит внешний инструмент. NextPDF не имеет сертификации и не предоставляет её; поддержка профиля не является соответствием ему. Результаты проверки — это технические записи проверки структуры для справки, а не юридическое заключение; обратитесь в вашу команду по соответствию, чтобы оценить нормативную достаточность.
Заметки по разработке
Заголовок раздела «Заметки по разработке»- Оператор размещает и эксплуатирует sidecar-ы, фиксирует их версии, ограничивает их сетевую досягаемость, проверяет их TLS и контролирует окружение, включающее необязательный режим. Конечные точки sidecar — это граница доверия; средства контроля резидентности и хранения для документов, результатов и логов — ответственность оператора.
- Вывод
buildComplianceMatrix()предназначен для прослеживаемости в CI: зафиксируйте commit SHA и архивируйте матрицу рядом с артефактами сборки. - Раннер XRechnung ожидает официальный набор тестов, распакованный в локальный каталог; сообщение его конструктора называет публичный источник загрузки.
- Внутренние детали механизма остаются во внутренней документации репозитория исходного кода и выходят за рамки этого руководства.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов руководств по эксплуатации и префиксы тикетов выходят за рамки.
См. также
Заголовок раздела «См. также»- Обзор возможности Compliance
- Validation — глубокий справочник
- Evidence — глубокий справочник
- Pro Compliance — внутрипроцессные электронные счета (отдельная поверхность)
- Core Conformance