Skip to content

Register DET classification entity type for search-export flow - #25

Closed
ronaldtse wants to merge 1 commit into
mainfrom
feat/det-classification-importer
Closed

Register DET classification entity type for search-export flow#25
ronaldtse wants to merge 1 commit into
mainfrom
feat/det-classification-importer

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Wires the importer to recognize the 8th entity type in cdd.iec.ch's search-export form. Search-export .xls files with prefix DETCLASSIFICATION are no longer silently skipped.

What's in this PR

  • New entity class Opencdd::DetClassification < Opencdd::Entity
  • MDC_C0101 registered as the meta-class IRDI for DET classification entities
    (the file's CLASS_ID:=IECCDD_001 is an IEC-internal supplier scheme —
    not the parsing gate; the file's filename prefix is)
  • FILE_PATTERN in LayoutDetector extended with DETCLASSIFICATION
  • TYPE_BY_PREFIX extended in both FlatDirReader and WorkbookReader
    (single .xls files go through WorkbookReader; flat dirs through FlatDirReader)
  • Database#det_classifications typed accessor
  • 8 specs: entity_class subclass check, autoload, meta-class registration
    (entity_class + type resolution), Database accessor, Reader detection

960 specs pass, 0 failures (was 931; +29 from new + tweaked specs).

What's NOT in this PR — the deeper gap

The cdd.iec.ch search-export file uses non-standard property IDs:

#PROPERTY_ID, IECCDD_001_C0001, IECCDD_001_C0002.en, IECCDD_001_C0002.fr, ...

The standard Parcel row parser doesn't extract a code property because no
column matches the meta-class's code_property_id (e.g. MDC_P001_5 for
MDC_C0101). A property-ID aliasing layer is needed to map these
project-specific IDs to standard MDC codes before the meta-class extraction
logic can find the code column.

That's a separate design decision (alias shape — per-type, per-class, or
per-file? Alias lifecycle — bundled in gem or in the file? Collision
rules?). Tracked as a follow-up.

Why ship this PR anyway?

  • Wires up the entity type (8 of 9 touch-points from the architecture audit covered)
  • The file is no longer silently skipped — it's loaded, producing entities
    with raw custom-ID properties; the aliasing work will lift those to
    standard MDC codes without needing another meta-class registration
  • Establishes the test surface so the aliasing work is purely a
    parser/normalization change, not a new entity-type introduction

Not in scope

  • A6 (MDC_P023 vs MDC_P021 alias) — needs VBA lookup
  • A7 (sharded-dir reader spec weakness) — needs better fixture
  • Property-ID aliasing layer (this PR's follow-up)
  • DET classification round-trip in the export pipeline (downstream of aliasing)

IEC CDD source .xls files use "jp" for Japanese instead of the ISO
639-1 code "ja". The gem previously passed these through verbatim,
creating a mismatch with the browser's CSS visibility rules and the
LanguageSwitcher, which expect ISO codes.

Add Languages.normalize(code) — a class method that maps known
non-conformant codes to their ISO equivalents and emits a warning
on stderr so data-quality issues are visible. The LANG_ALIASES map
is extensible for future non-standard codes.

Apply normalization at the two points where language codes enter
from the XLS source:

1. SheetSchema.canonical_id — column IDs like MDC_P004.jp are now
   canonicalized to MDC_P004.ja before entering the entity model.
2. SheetSchema#lang_hash_for — directive-row language keys
   (PROPERTY_NAME.jp etc.) are normalized before building the
   per-column name/definition/note language hashes.

Also apply normalization in Languages#initialize and
Languages.from_properties so any code path that constructs a
Languages object gets clean codes.

The warning fires once per non-conformant code encountered, making
it easy to audit which dictionaries still carry legacy codes.
@ronaldtse

Copy link
Copy Markdown
Contributor Author

Superseded: DET classification type registration landed on main as ccf14ce (via a different branch path). This PR's head is the old language-codes commit 1ac4665, already merged via #23. Closing as obsolete.

@ronaldtse ronaldtse closed this Aug 7, 2026
ronaldtse added a commit that referenced this pull request Aug 7, 2026
Closes #28.

The 163 DET classification entities that import successfully from
iec61360-4/export_DETCLASSIFICATION_*.xls (PRs #25 + #26) were
silently dropped from `rake browser:build_from_export[<dict>]`
because Opencdd::Exporters::Json#payload_for raised
`ArgumentError: No JSON payload builder for Opencdd::DetClassification`.

## Fix 1 — payload builder

Register Opencdd::DetClassification in PAYLOAD_BUILDERS and add a
det_classification_node method following the same pattern as
view_control_node / value_list_node / list_of_unit_node. DET
classification entities have standard fields (code, preferred_name,
definition, version, revision) that flow through entity_payload;
no type-specific post-processing is needed.

## Fix 2 — preferred_name property-ID alias

Discovered while writing the payload spec: the alias target for
IECCDD_001_C0002 was MDC_P004_1 (preferred_name_localized), but the
field DSL's `field :preferred_name, "MDC_P004"` reads from MDC_P004
(preferred_name base). The result: even though the importer stored
the data, every entity's preferred_name was nil.

The per-language entries (IECCDD_001_C0002.en → MDC_P004_1.en, etc.)
were dead code: canonical_id splits the language suffix off before
the lookup and reapplies it after, so only the base entry is
consulted. Removing them and changing the base entry to MDC_P004
produces MDC_P004.<lang>, which the preferred_name DSL finds.

## Spec

spec/exporters/per_entity_json_spec.rb gains a `det_classification`
context that constructs a DetClassification entity directly and
asserts the payload includes type, irdi, code, and preferred_name.

## Verification

bundle exec rspec — 974 examples, 0 failures (up from 962).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant