package iace // Norm cross-reference matrix: maps a core ISO/IEC/EN standard to the // jurisdiction-specific identifiers used in DIN (DE), ANSI / NFPA / UL (US), // GB (China), and JIS (Japan). This is an identifier-only mapping — no // copyrighted norm text is included. The matrix is used to render a // "this requirement also satisfies X in market Y" hint in tech files, // enabling dual-use compliance documents for CE + US/CN/JP export. // // IMPORTANT: each NormMapping carries an explicit Confidence and Relation. // Do NOT treat "partial" or "medium" entries as 1:1 substitutes. They // indicate scope overlap that must be verified by a competent person for // the concrete machine before relying on the foreign standard. // NormMapping is one entry in the cross-reference table. type NormMapping struct { Region string `json:"region"` // "EU-DIN", "US-ANSI", "US-NFPA", "US-UL", "US-OSHA", "CN-GB", "JP-JIS", "INTL-ISO" Identifier string `json:"identifier"` // e.g. "DIN EN ISO 12100:2011" Relation string `json:"relation"` // "identical", "equivalent", "partial", "supersedes", "superseded_by" Confidence string `json:"confidence"` // "verified", "high", "medium", "low" Notes string `json:"notes,omitempty"` // Optional scope clarification (e.g. "only chapters 4-6") SourceURL string `json:"source_url,omitempty"` // Optional pointer to a public catalog entry } // NormCrossRef is the cross-reference entry for one NormReference.ID. type NormCrossRef struct { NormID string `json:"norm_id"` // Matches NormReference.ID (e.g. "ISO-12100") Mappings []NormMapping `json:"mappings"` // International equivalents Notes string `json:"notes,omitempty"` // General notes about the cross-walk BatchID string `json:"batch_id"` // Tracking which batch added this entry } // crossRefRegistry is the in-memory registry, populated by init() in each batch file. var crossRefRegistry = map[string]NormCrossRef{} // registerCrossRefs is called by each batch file's init() to append entries. func registerCrossRefs(entries []NormCrossRef) { for _, e := range entries { crossRefRegistry[e.NormID] = e } } // GetNormCrossRef returns the cross-reference entry for a given NormReference.ID, // or a zero value with NormID set if no mapping exists yet. func GetNormCrossRef(normID string) NormCrossRef { if entry, ok := crossRefRegistry[normID]; ok { return entry } return NormCrossRef{NormID: normID, Mappings: []NormMapping{}} } // ListNormCrossRefs returns every entry in the registry. Used by the // /norms-library/crossref bulk endpoint and for tech-file batch rendering. func ListNormCrossRefs() []NormCrossRef { out := make([]NormCrossRef, 0, len(crossRefRegistry)) for _, v := range crossRefRegistry { out = append(out, v) } return out } // CrossRefCoverage returns counters that let the UI render a progress bar // ("X of Y norms have a cross-reference"). The "total" comes from the // caller (norms library size) since the cross-ref package does not depend // on the norms library to avoid a cyclic import. func CrossRefCoverage(totalNorms int) (covered, total int) { return len(crossRefRegistry), totalNorms }