Repository navigation
fix: keep legal mentions, route buyers on their SIREN and surface PDP rejections - #21
Merged
Merged
Conversation
… rejections Invoice 2026015 was rejected by the platform (fr:213) although the local EN 16931 validator had passed it. Three defects lined up. Notes replaced the legal mentions. A single context note in the spec dropped PMD, PMT and AAB from the CII, which violates BR-FR-05. Notes are now merged: the three mentions are always emitted, a spec note carrying one of these codes replaces the default of the same code, and a note without subject_code goes out as AAI. Validate enforces exactly one note per legal code, so neither the CLI nor create_invoice can produce a file that lacks one. The buyer was routed on its e-mail. Without electronic_address, BT-49 was EM:<email>, which no directory knows. Buyers now resolve like sellers: explicit address, else SIREN (derived from the SIRET) with scheme 0225, else e-mail only when no legal identifier exists. create_invoice writes the resolved address into the sidecar so the file reflects the XML, and send_invoice refuses a buyer whose address is not routable (0225/0002) instead of letting the platform reject it. The rejection reason never reached the user. The SuperPDP client only read status_code and status_text; the reasons live in data.reason and details[].notes[].contents[]. They are decoded, exposed on each event, summarised as rejected/reasons by send_invoice and get_invoice_status, and journaled as pdp_rejected. send_invoice reads the lifecycle once right after the deposit, so a rejection comes back immediately rather than as api:uploaded. The CLI prints them too. Also: an optional title field is the registry's project label, with the first line name as last resort only. Documentation, the MCP prompt and the tool schema describe the new behaviour. Existing sidecars load unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up of the SuperPDP rejection of invoice 2026015 (
fr:213, BR-FR-05). Three root causes and one minor defect, each with tests.Legal mentions survive user notes. Spec notes are merged with PMD/PMT/AAB instead of replacing them; a note without
subject_codebecomesAAI; a note carrying a legal code replaces the default of that code.Validateenforces exactly one note per legal code (BR-FR-05), so the CLI andcreate_invoicerefuse before generation.Buyer routing (BT-49). Resolution order: explicit
electronic_address→ SIREN (from SIRET) in0225→ e-mail inEMonly without any legal identifier.create_invoicewrites the resolved address into the sidecar;send_invoicerefuses a buyer whose scheme is not0225/0002and points tofind_routing_address.Rejection reasons. The SuperPDP client decodes
data.reasonanddetails[].notes[].contents[].content;send_invoicere-reads the lifecycle right after the deposit and returns the rejection with its reasons line by line;get_invoice_statusexposesrejected/reasons; the journal getspdp_rejected; the CLI prints them.Registry label. New optional
titlefield used asprojet, first line name as last resort.Tests: notes merge and BR-FR-05 (
spec_test,rules_test), buyer routing, a regression replaying the 2026015 spec, SuperPDP reason decoding, and MCP tests for the sidecar routing, the refusal and a mockedfr:213(httptest). Existing sidecars load unchanged.Local CI replay:
act -j crossgreen;testandoraclecannot run under act (Chrome fails to start in the container), sogo vet ./...,go test ./...andgo test -tags=ci ./internal/facturx -run TestOraclewere replayed by hand with a real Chrome and Java — all green, MustangPDF:valid XML:valid.