docs: prevent double-decoding CVP IS links
Validate skill / validate (push) Successful in 4s

This commit is contained in:
2026-09-03 06:09:08 +00:00
parent 53923ee180
commit f0f3322a9a
2 changed files with 3 additions and 0 deletions
+1
View File
@@ -291,6 +291,7 @@ Examples of valid skill improvements: a newly confirmed procurement search route
19. Collapsing repeated generic labels into one cross-client system. “Official website”, “institution portal”, and similar phrases may describe different client-specific resources; scope them to the client unless direct evidence proves a shared identity. Conversely, preserve reviewed aliases for clearly identical named products instead of producing duplicate registry entries. 19. Collapsing repeated generic labels into one cross-client system. “Official website”, “institution portal”, and similar phrases may describe different client-specific resources; scope them to the client unless direct evidence proves a shared identity. Conversely, preserve reviewed aliases for clearly identical named products instead of producing duplicate registry entries.
20. Introducing a new contractor identity by casually changing legal-designator or consortium wording in one observation. Before writing a contractor cell, inspect the generated contractor registry and existing canonical observations for that supplier. Reuse the established exact entity label when it denotes the same evidenced entity; keep a consortium phrase separate from the standalone company, and do not prepend `UAB` to an established `„Company“ su konsorciumo partneriais` label unless evidence and reviewed identity rules justify changing that composite identity. After generation, compare contractor counts and inspect all near-name matches; an unexpected increase commonly signals accidental fragmentation rather than a new contractor. 20. Introducing a new contractor identity by casually changing legal-designator or consortium wording in one observation. Before writing a contractor cell, inspect the generated contractor registry and existing canonical observations for that supplier. Reuse the established exact entity label when it denotes the same evidenced entity; keep a consortium phrase separate from the standalone company, and do not prepend `UAB` to an established `„Company“ su konsorciumo partneriais` label unless evidence and reviewed identity rules justify changing that composite identity. After generation, compare contractor counts and inspect all near-name matches; an unexpected increase commonly signals accidental fragmentation rather than a new contractor.
21. Flattening an award's winner, participant-group leader and subcontractor into one generic contractor attribution. Read the award body's official winner name, any `Pirkimų procedūros dalyvio vadovas` / participant-group leader label, and subcontracting fields separately. Preserve the official selected supplier as the winner; treat a separately displayed participant-group leader only as portal metadata unless the body explicitly establishes a distinct legal entity and role; preserve an explicitly named subcontractor with its stated share/value and bounded subcontractor role. Do not concatenate these labels into one contractor identity or infer consortium membership, co-award, implementation scope, production use, or hosting. See [`references/cvp-is-organization-route.md`](references/cvp-is-organization-route.md) for the award extraction checklist. 21. Flattening an award's winner, participant-group leader and subcontractor into one generic contractor attribution. Read the award body's official winner name, any `Pirkimų procedūros dalyvio vadovas` / participant-group leader label, and subcontracting fields separately. Preserve the official selected supplier as the winner; treat a separately displayed participant-group leader only as portal metadata unless the body explicitly establishes a distinct legal entity and role; preserve an explicitly named subcontractor with its stated share/value and bounded subcontractor role. Do not concatenate these labels into one contractor identity or infer consortium membership, co-award, implementation scope, production use, or hosting. See [`references/cvp-is-organization-route.md`](references/cvp-is-organization-route.md) for the award extraction checklist.
22. Decoding a CVP IS link twice after an HTML parser has already decoded its attribute entities. Libraries such as Beautiful Soup normally return `href` with `&` decoded to `&`; a second generic `html.unescape()` can reinterpret the start of `&noticeType` as the legacy `&not` entity and silently corrupt it to `¬iceType`. Use the parser-returned attribute directly with `urljoin`, and assert that expected query keys such as `resourceId`, `documentId`, `noticeType`, and `noticeId` survived before fetching. If parsing raw HTML without a DOM parser, decode `&` exactly once rather than applying an unrestricted second entity pass.
## Verification Checklist ## Verification Checklist
+2
View File
@@ -45,6 +45,8 @@ Live validation on 2026-08-19 used `resourceId=9279980`. All three routes return
7. Parse each HTML table row as a record. The notice **type** is commonly an anchor in the first cell, while the procurement **title** is plain text in the second cell—not an anchor. Therefore, anchor-text extraction alone can falsely report zero IT candidates even when a relevant title is visible. Extract and normalize all cells, keep the first-cell attachment URL, then keyword-filter the second-cell title. 7. Parse each HTML table row as a record. The notice **type** is commonly an anchor in the first cell, while the procurement **title** is plain text in the second cell—not an anchor. Therefore, anchor-text extraction alone can falsely report zero IT candidates even when a relevant title is visible. Extract and normalize all cells, keep the first-cell attachment URL, then keyword-filter the second-cell title.
8. Open promising notice-type links. They can be forced PDF attachments rather than HTML pages. 8. Open promising notice-type links. They can be forced PDF attachments rather than HTML pages.
When a DOM/HTML parser has already decoded attribute entities, pass its `href` value directly to `urljoin`; do not apply `html.unescape()` again. A second generic unescape can reinterpret the beginning of the real `&noticeType` query key as the legacy `&not` entity and produce a corrupted `¬iceType` parameter. Before fetching a retained notice link, parse its query and require the expected keys (`resourceId`, `documentId`, `noticeType`, and `noticeId` when present). When working from raw HTML instead, decode `&` once and perform the same key check.
## Direct PDF behavior ## Direct PDF behavior
A notice link commonly has this form: A notice link commonly has this form: