Skip to content

Fix SSB size/NACE mapping — off-by-one på alle størrelser, eksplisitt no-coverage-håndtering#2

Open
hassanzouhar wants to merge 6 commits intomainfrom
fix/ssb-size-nace-mapping
Open

Fix SSB size/NACE mapping — off-by-one på alle størrelser, eksplisitt no-coverage-håndtering#2
hassanzouhar wants to merge 6 commits intomainfrom
fix/ssb-size-nace-mapping

Conversation

@hassanzouhar
Copy link
Copy Markdown
Owner

@hassanzouhar hassanzouhar commented May 5, 2026

Summary

Fikser systematisk feil-mapping mellom DMSA og SSBs sysselsettings/NACE-koder, og bringer no_bus-mappinglogikken inn i hovedrepoet (lå tidligere i et nestet working tree uten remote).

Mapping-feilene som rettes:

  • mapSizeToSSBCode returnerte '02' (= 10-19) for DMSA 'micro' — men SSB har INGEN data for 1-9-foretak. Resultat: alle størrelser var off-by-one.
  • 'small' mappet til '03' alene (= 20-49) i stedet for ['02','03'] (= 10-49).
  • 'medium' mappet til '04' alene (= 50-99) i stedet for ['04','05'] (= 50-249).
  • Sektorer uten SSB ICT-bruk-dekning (A, B, O, P, Q, T, U) ble behandlet som om de var dekket — fall-back til 'Total' skjulte hullene stille.

Endringer

# Fil Hva
1 data/nace-sectors.ts Legg til ssbCoverage ('full' / 'partial' / 'none') og ssbNaceCodes på hver av de 21 sektorene
2 no_bus/entities/nace-sectors.ts Speil av (1) — holdes alltid identisk
3 no_bus/lib/ssb-mapping.ts (ny) Canonical mapping-fil. Eksporterer mapSizeToSSBCodes (plural — returnerer array siden DMSA-størrelser aggregerer flere SSB-koder), mapSectorToNaceCodes, hasSSBCoverage, SSB_NO_COVERAGE_REASON
4 no_bus/lib/ssb-api-client.ts Bruker ssb-mapping. getTableDataBySegment kortslutter med { data: null, reason: 'no-ssb-coverage' } ved tom array. Sender array-valueCodes når flere koder. Gamle private mappere er deprecated wrappers
5 no_bus/lib/ssb-transformer.ts + no_bus/src/mapping/dimensionMapping.ts tableMapping flyttet til dimensionMapping (canonical). Transformer importerer derfra. Duplikat resolveSectorCodes og mapSizeToSSBCode slettet — bruker ssb-mapping
6 no_bus/script/extract-ssb-benchmarks.ts Filtrerer bort sektorer uten SSB-dekning ved oppstart. Avbryter på --size micro. Detekterer no-coverage-sentinel per tabell

Verifisering

Sanity-test for mapping-funksjonene (alle 12 cases bestått):

mapSizeToSSBCodes('small')   → ['02','03']   (10-19 + 20-49 = 10-49)
mapSizeToSSBCodes('medium')  → ['04','05']   (50-99 + 100+; '05' inkluderer 250+ — lossy)
mapSizeToSSBCodes('large')   → ['05']        (100+ er beste tilgjengelige proxy for 250+)
mapSizeToSSBCodes('micro')   → []            (SSB ICT-bruk har ikke 1-9)
mapSectorToNaceCodes('G')    → ['45','46','47']
mapSectorToNaceCodes('K')    → ['64-66']
mapSectorToNaceCodes('F')    → ['41-43']
mapSectorToNaceCodes('C')    → ['10-39']     (aggregat med D+E)
mapSectorToNaceCodes('O')    → []            (offentlig admin — ingen ICT-bruk)
mapSectorToNaceCodes('A')    → []            (jordbruk — ingen ICT-bruk)
hasSSBCoverage('G')          → true
hasSSBCoverage('O')          → false

TypeScript: npx tsc --noEmit introduserer ingen nye feil i endrede filer.

Out-of-scope (per spec)

  • Tabell-utvalget (10 av 75 mulige) — venter på senere PR
  • DMSA-spørsmålsendringer (Q5/Q6/Q10/Q11 har lav SSB-coverage)
  • Capgemini UI-rammeverk
  • Firestore reseed (separat operasjon etter merge)
  • Vektet snitt mot foretakspopulasjon — TODO-merket i koden, første pass bruker uvektet via SSB multi-value-query

Reviewer notes

  • Vercel build feiler med Module not found: '@/components/benchmark/BenchmarkSection' — dette er pre-eksisterende i app/results/page.tsx:36 og components/modals/ExtendedResultsModal.tsx:19, ikke introdusert av denne PR-en. Bekreft separat.
  • Codex P1-kommentarerapp/api/benchmarks/averages/route.ts og app/api/surveys/[id]/complete/route.ts gjelder eksisterende kode i main, ikke endringer i denne PR-en. De ble synlige da merge-base var skjev før rebase. Etter denne push-en bør Codex kun kommentere på filene som faktisk endres her.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dmsa Error Error May 5, 2026 5:48am

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 071454abed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +34 to +35
.where('state', '==', 'completed')
.where('flags.includeInLeaderboard', '==', true)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Query completion using stored survey flags

This endpoint filters with state == 'completed', but surveys are created with state: 'T0'/'T1' and completion is tracked via flags.isCompleted (see survey creation/completion flow). As a result, the sector/size/county queries never match completed records, so benchmark averages silently come back empty for real users. Use the same completion fields as the rest of the data layer (e.g. flags.isCompleted + flags.hasResults).

Useful? React with 👍 / 👎.

Comment on lines +345 to +347
await db.collection('surveys').doc(surveyId).update({
'flags.isAnonymous': isAnonymous
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist leaderboard opt-out on includeInLeaderboard flag

The PATCH handler only updates flags.isAnonymous, but leaderboard inclusion checks flags.includeInLeaderboard (lib/leaderboard-service.ts) and the UI toggle in app/results/page.tsx is presented as include/exclude from leaderboard. This means users can get a success response while their leaderboard participation never actually changes server-side, which breaks the opt-out flow.

Useful? React with 👍 / 👎.

Hassan Zouhar and others added 6 commits May 5, 2026 07:46
Beriker hver av de 21 NACE-sektorene med metadata om SSB ICT-bruk-dekning.
Tre nivåer ('full' / 'partial' / 'none') gjør det eksplisitt for nedstrøms
kode hvilke sektorer som faktisk kan benchmarkes mot SSB ICT-bruk-tabellene
og hvilke som mangler dekning helt (A, B, O, P, Q, T, U).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Holder no_bus-duplikatet i synk med data/nace-sectors.ts. Begge filer er
canonical for sin respektive importsti — innholdet skal alltid være
identisk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Konsoliderer DMSA→SSB-koder på ett sted. Eksporterer:
- mapSizeToSSBCodes(size): string[] — returnerer array siden flere
  DMSA-størrelser aggregerer flere SSB-koder
  (small=['02','03'], medium=['04','05'], large=['05'], micro=[])
- mapSectorToNaceCodes(sector): string[] — leser ssbNaceCodes fra
  entities/nace-sectors.ts; returnerer [] for sektorer uten dekning
- hasSSBCoverage(sector): boolean
- SSB_NO_COVERAGE_REASON: 'no-ssb-coverage' sentinel

Tidligere hadde ssb-api-client.ts og ssb-transformer.ts hver sin
ulike versjon — nå er begge import-konsumenter av denne.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…joner

- Importer mapSizeToSSBCodes/mapSectorToNaceCodes fra ./ssb-mapping
- getTableDataBySegment kortslutter med sentinel
  { data: null, reason: 'no-ssb-coverage' } når sektor eller størrelse
  mangler SSB ICT-bruk-dekning, før noe SSB-kall gjøres
- Sender array-valueCodes når mappingen returnerer flere koder
  (f.eks. small → ['02','03'])
- Gamle private mapSizeToSSBCode/mapSectorToSSBCode er nå tynne deprecated
  wrappers som delegerer til canonical
- Fjerner stille fall-back til 'Total' for sektorer uten dekning — det
  skjulte dekningshull mer enn det hjalp

Bringer denne filen, sammen med øvrige no_bus mapping-fix-filer, inn i
dmsa-repoet (lå tidligere i nestet working tree uten remote)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dimensionMapping.ts er nå canonical for tableMapping (med DimensionConfig-
type, indikatorer og fortegnsvekter per tabell). ssb-transformer.ts
importerer derfra og re-eksporterer for bakoverkompatibilitet.

I tillegg slettet i transformer:
- duplikat resolveSectorCodes (hardkodet sektor→NACE-mapping) → bruker
  mapSectorToNaceCodes fra ssb-mapping
- duplikat mapSizeToSSBCode → wrapper rundt mapSizeToSSBCodes (plural)
  med TODO om at extractDataFromJSONStat bør iterere over alle koder

SsbProxies (string[]-versjonen) er nå avledet fra tableMapping for å
unngå at de kommer ut av synk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-code

- Filtrerer bort sektorer med ssbCoverage === 'none' (A, B, O, P, Q, T, U)
  ved oppstart — disse vil bare returnere no-ssb-coverage-sentinels
- Avbryter eksplisitt med feilmelding når --size micro oppgis (SSB
  ICT-bruk har ingen 1-9-data)
- Detekterer no-ssb-coverage-sentinel per tabell og hopper pent over
  i stedet for å forsøke transformere null-data
- Fjerner brutt SSB_TABLE_MAPPING-import (eksisterte aldri som eksport)
- TODO-kommentar: i dag sender vi multi-value-listen rett til SSB API og
  bruker uvektet snitt nedstrøms. Vektet snitt mot foretakspopulasjon
  (12936/07091) gjenstår som forbedring

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hassanzouhar hassanzouhar force-pushed the fix/ssb-size-nace-mapping branch from 071454a to c3079fa Compare May 5, 2026 05:47
@hassanzouhar hassanzouhar changed the title Fix SSB size/NACE mapping — legg til coverage-metadata på sektorer Fix SSB size/NACE mapping — off-by-one på alle størrelser, eksplisitt no-coverage-håndtering May 5, 2026
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