@mostajs/nomenclature 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +64 -0
- package/llms.txt +54 -0
- package/package.json +45 -0
- package/src/index.js +8 -0
- package/src/memory-repo.js +7 -0
- package/src/nomenclature.js +83 -0
- package/src/schemas.js +13 -0
- package/src/seed-all.js +19 -0
- package/src/seed-ccam.js +32 -0
- package/src/seed-cim10.js +47 -0
- package/src/seed-naa-dz.js +86 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog — @mostajs/nomenclature
|
|
2
|
+
|
|
3
|
+
Format [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) · [SemVer](https://semver.org/lang/fr/).
|
|
4
|
+
Auteur : Dr Hamid MADANI <drmdh@msn.com>
|
|
5
|
+
|
|
6
|
+
## [0.2.0] — 2026-06-21
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- **Seed `cim-10`** (CIM-10 / ICD-10, OMS) — extrait **représentatif oncologie** (tumeurs malignes C00–C97 : racine, blocs, catégories C16/C18/C22/C25/C34/C50/C53/C56/C61/C64/C67/C73/C81/C85/C90/C91/C92, sous-catégories `.9`). Export `CIM_10` + sous-chemin `./seed-cim10`.
|
|
10
|
+
- **Seed `ccam`** (actes médicaux — logique CCAM) — imagerie (TDM/IRM/écho/TEP/DMO), spécialisés (coroscanner, scintigraphie), biologie (NFS/marqueurs), anatomopathologie (histologie/cytologie). Codes **illustratifs** ; charger CCAM/NABM/ADICAP officiels via `dataset` en prod. Export `CCAM` + `./seed-ccam`.
|
|
11
|
+
- **Bundles par métier** (`src/seed-all.js`) : `HEALTH_SEEDS` (cim-10 + ccam, pour l'app santé — P3 Salsabil), `ACTIVITY_SEEDS` (naa-dz), `ALL_SEEDS` (rare), `BUILTIN_SCHEMES`. Exportés.
|
|
12
|
+
- **Principe « chacun dans son métier »** : chaque app seede **le(s) schéma(s) de son domaine** — l'app santé injecte `dataset: HEALTH_SEEDS` ; l'app activités garde le **défaut `naa-dz`**. Pas de mélange de domaines par défaut.
|
|
13
|
+
- Tests étendus (santé : `schemes.list`, `validate`, `path` pointé, `children`, recherche, **cloisonnement** entre schémas). Design doc : `docs/DESIGN-SEEDS-CIM10-CCAM.md`.
|
|
14
|
+
|
|
15
|
+
### Unchanged (rétro-compat SemVer)
|
|
16
|
+
- **Défaut inchangé** = `naa-dz` (Hadhinat/activités non impacté). Aucune rupture d'API.
|
|
17
|
+
- Codes normalisés **sans points** (`C50.9` → `C509`) ; forme canonique pointée dans le libellé.
|
|
18
|
+
|
|
19
|
+
## [0.1.0] — 2026-06-19
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- Référentiel de **nomenclatures hiérarchiques** (codes d'activité officiels) — couvre le besoin **O4** Hadhinat (choix d'un code d'activité officiel), transverse (CRM/billing/reporting/déclarations légales). Feuille de route **E1**.
|
|
23
|
+
- `createNomenclature({ repositories, dataset?, defaultScheme?, i18n? })` — façade composant `repositories`/`@mostajs/orm` (persistance), `@mostajs/i18n` (libellés FR/AR), `@mostajs/data-plug` (import). **Responsabilité unique** : charger / rechercher / valider / résoudre.
|
|
24
|
+
- **Codes** : `search` (préfixe de code OU plein texte FR/AR, insensible casse+accents), `get`, `children` (arbre), `validate`, `path` (fil d'Ariane racine→feuille), `label` (FR/AR).
|
|
25
|
+
- **Schémas** : `schemes.list`, `schemes.tree` (racines niveau 1). Normalisation des codes (majuscules, sans espaces ni points).
|
|
26
|
+
- **Seed livré `naa-dz`** : Nomenclature Algérienne des Activités (alignée CITI Rev.4 / NACE ; réf. CNRC & ONS NAA-NAP) — extrait représentatif multi-sections, descendu au **niveau 5** sur la branche 62 (informatique). Extensible par `dataset` injecté.
|
|
27
|
+
- Entité `NomenclatureCodeSchema` (5 niveaux : section/division/groupe/classe/activité) + `createMemoryRepositories`.
|
|
28
|
+
- 7 tests unitaires + exemple `examples/activites` (sélecteur de code d'activité). Proposition `docs/00-PROPOSITION-PLAN-NOMENCLATURE-19062026.md`.
|
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# @mostajs/nomenclature
|
|
2
|
+
|
|
3
|
+
> Référentiel de **nomenclatures hiérarchiques** — charger, **rechercher**, **valider** et **résoudre** des codes d'activité officiels.
|
|
4
|
+
|
|
5
|
+
**Auteur** : Dr Hamid MADANI <drmdh@msn.com> · **Licence** : AGPL-3.0-or-later
|
|
6
|
+
|
|
7
|
+
Module **mince** à responsabilité unique. Aucune logique métier : il modélise un **arbre de codes** (`section → division → groupe → classe → activité`) consultable et validable. Transverse — il sert la pépinière (**O4** Hadhinat : *« choisir le code exact de l'activité parmi la liste officielle »*) comme le CRM, la facturation, le reporting ou les déclarations légales.
|
|
8
|
+
|
|
9
|
+
Schéma livré : **`naa-dz`** — *Nomenclature Algérienne des Activités* (alignée CITI Rev.4 / NACE ; réf. **CNRC** & **ONS** NAA-NAP). Extensible (`naf-fr`, `nace-eu`…) par simple `dataset` injecté.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @mostajs/nomenclature
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { createNomenclature, createMemoryRepositories } from '@mostajs/nomenclature';
|
|
21
|
+
|
|
22
|
+
const nom = createNomenclature({ repositories: createMemoryRepositories() }); // seed 'naa-dz' livré
|
|
23
|
+
|
|
24
|
+
await nom.codes.search('informatique'); // → propositions (préfixe code OU plein texte FR/AR)
|
|
25
|
+
await nom.codes.validate('62011'); // → { ok:true, normalized:'62011', label:'…', level:5 }
|
|
26
|
+
await nom.codes.path('62011'); // → [J › 62 › 620 › 6201 › 62011] (fil d'Ariane)
|
|
27
|
+
await nom.codes.children('J'); // → divisions de la section J
|
|
28
|
+
await nom.codes.label('62011', { lang:'ar' }); // → 'تطوير البرمجيات حسب الطلب'
|
|
29
|
+
await nom.schemes.tree(); // → sections (racines)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
En production, injecter de vrais repositories `@mostajs/orm` et un `dataset` complet :
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
import { createNomenclature } from '@mostajs/nomenclature';
|
|
36
|
+
const nom = createNomenclature({ repositories: ormRepos, dataset: jeuOfficielComplet, i18n });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
| Méthode | Retour |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `codes.search(q, { scheme?, limit?, level?, activeOnly? })` | `[{ scheme, code, label, level, parentCode }]` — préfixe de code **ou** plein texte (insensible casse+accents, FR/AR) |
|
|
44
|
+
| `codes.get(code, { scheme? })` | `{ scheme, code, label, labelAr, parent, level, active }` \| `null` |
|
|
45
|
+
| `codes.children(code, { scheme? })` | sous-codes directs |
|
|
46
|
+
| `codes.validate(code, { scheme? })` | `{ ok, normalized, label, level }` \| `{ ok:false, reason }` |
|
|
47
|
+
| `codes.path(code, { scheme? })` | `[{code,label,level}…]` racine → feuille |
|
|
48
|
+
| `codes.label(code, { scheme?, lang })` | libellé résolu (`fr`\|`ar`) |
|
|
49
|
+
| `schemes.list()` / `schemes.tree({ scheme? })` | schémas présents / racines (niveau 1) |
|
|
50
|
+
|
|
51
|
+
## Composition (injection)
|
|
52
|
+
|
|
53
|
+
`repositories` (**obligatoire**) · `dataset` (défaut = seed `naa-dz`) · `i18n` (libellés FR/AR) · `data-plug` (import). Les codes sont **normalisés** (majuscules, sans espaces ni points : `62.01` → `6201`).
|
|
54
|
+
|
|
55
|
+
> **Niveaux** : `1` section (lettre A…U) · `2` division (2 ch.) · `3` groupe (3) · `4` classe (4) · `5` activité nationale (5).
|
|
56
|
+
|
|
57
|
+
## Tests & exemple
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm test # 7 tests unitaires
|
|
61
|
+
npm run example # sélecteur de code d'activité (O4)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Voir `docs/00-PROPOSITION-PLAN-NOMENCLATURE-19062026.md` (cas C, étape E1).
|
package/llms.txt
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# @mostajs/nomenclature — llms.txt
|
|
2
|
+
|
|
3
|
+
RÔLE
|
|
4
|
+
Référentiel de NOMENCLATURES hiérarchiques (codes d'activité officiels). Responsabilité UNIQUE : charger,
|
|
5
|
+
rechercher, valider et résoudre des codes liés par parentCode (section → division → groupe → classe → activité).
|
|
6
|
+
AUCUNE logique métier. Transverse : pépinière (O4 Hadhinat : choix d'un code d'activité officiel), CRM,
|
|
7
|
+
facturation, reporting, déclarations légales, SANTÉ (diagnostic/examens). Schémas livrés : 'naa-dz' (activités,
|
|
8
|
+
CNRC/ONS, CITI/NACE), 'cim-10' (diagnostics OMS/ICD-10 — oncologie représentative), 'ccam' (actes médicaux —
|
|
9
|
+
imagerie/bio/anapath, codes illustratifs). Multi-schéma. Extensible (naf-fr, nace-eu, CCAM/NABM/ADICAP officiels…) par `dataset`.
|
|
10
|
+
MÉTIER : "chacun dans son métier" — l'app santé injecte HEALTH_SEEDS (cim-10+ccam) ; l'app activités garde le défaut naa-dz.
|
|
11
|
+
Bundles : HEALTH_SEEDS, ACTIVITY_SEEDS, ALL_SEEDS (rare), BUILTIN_SCHEMES. Seeds : CIM_10, CCAM, NAA_DZ. Sous-chemins ./seed-cim10 ./seed-ccam.
|
|
12
|
+
|
|
13
|
+
COMPOSE (injection de dépendances)
|
|
14
|
+
repositories OBLIGATOIRE — { codes }. Persistance + recherche. createMemoryRepositories() pour tests ;
|
|
15
|
+
vrais repos @mostajs/orm en prod.
|
|
16
|
+
dataset jeu de codes à charger ; défaut = seed 'naa-dz' livré. Idempotent (skip si (scheme,code) existe).
|
|
17
|
+
i18n @mostajs/i18n — résolution de libellés FR/AR si non portés par la donnée (optionnel).
|
|
18
|
+
data-plug @mostajs/data-plug — import de gros référentiels officiels (CSV/JSON) → dataset (côté app).
|
|
19
|
+
HORS PÉRIMÈTRE : rattacher un code à une entreprise → cas B @mostajs/incubator 0.2.0 (Company.activityCode).
|
|
20
|
+
|
|
21
|
+
EXPORTS (src/index.js)
|
|
22
|
+
createNomenclature({ repositories, dataset?, defaultScheme='naa-dz', i18n? }) -> api
|
|
23
|
+
createMemoryRepositories() -> { codes }
|
|
24
|
+
NomenclatureCodeSchema (./schemas) ; NAA_DZ (./seed-naa-dz)
|
|
25
|
+
|
|
26
|
+
API (toutes async ; `await api.ready` ou appeler une méthode — le seed est chargé paresseusement)
|
|
27
|
+
codes.search(q, { scheme?, limit=20, level?, activeOnly=true }) -> [{ scheme, code, label, level, parentCode }]
|
|
28
|
+
recherche par PRÉFIXE de code OU PLEIN TEXTE de libellé (FR/AR, insensible casse+accents)
|
|
29
|
+
codes.get(code, { scheme? }) -> { scheme, code, label, labelAr, parent, level, active } | null
|
|
30
|
+
codes.children(code, { scheme? }) -> sous-codes directs (navigation arborescente)
|
|
31
|
+
codes.validate(code, { scheme? }) -> { ok:true, normalized, label, level } | { ok:false, reason }
|
|
32
|
+
codes.path(code, { scheme? }) -> [{code,label,level}…] fil d'Ariane racine→feuille ([] si absent)
|
|
33
|
+
codes.label(code, { scheme?, lang='fr'|'ar' }) -> libellé résolu
|
|
34
|
+
schemes.list() -> ['naa-dz', …] ; schemes.tree({ scheme? }) -> racines (level 1)
|
|
35
|
+
ready -> Promise (seed chargé) ; repositories
|
|
36
|
+
|
|
37
|
+
ENTITÉ (schema)
|
|
38
|
+
NomenclatureCode { scheme*, code*, label*, labelAr?, parentCode (null=racine), level (1..5), active }
|
|
39
|
+
Niveaux : 1 section (lettre A..U) · 2 division (2 ch.) · 3 groupe (3) · 4 classe (4) · 5 activité nationale (5).
|
|
40
|
+
|
|
41
|
+
PIÈGES
|
|
42
|
+
- Les codes sont NORMALISÉS : majuscules, sans espaces ni points ('62.01' / ' 6201 ' → '6201').
|
|
43
|
+
- search() est insensible aux accents (NFD) ET à la casse ; matche aussi le libellé arabe.
|
|
44
|
+
- validate() distingue 'code inconnu' (absent du schéma) de 'code inactif' (active:false).
|
|
45
|
+
- path()/children() suivent parentCode dans LE schéma demandé (defaultScheme sinon).
|
|
46
|
+
- Le seed 'naa-dz' est REPRÉSENTATIF (pas exhaustif) : breadth multi-sections, depth complète sur la branche 62
|
|
47
|
+
(informatique, jusqu'au niveau 5). Injecter un `dataset` complet en prod.
|
|
48
|
+
- DB-agnostique : injecter de vrais repositories @mostajs/orm en prod.
|
|
49
|
+
|
|
50
|
+
EXEMPLE / TEST
|
|
51
|
+
examples/activites/run.mjs sélecteur d'activité O4 : search → validate → path → arbre → libellé AR
|
|
52
|
+
test-scripts/unit/nomenclature.test.mjs 7 tests (seed, get/normalisation, children, validate, path, search, composition/dataset)
|
|
53
|
+
|
|
54
|
+
LICENCE AGPL-3.0-or-later · Auteur Dr Hamid MADANI <drmdh@msn.com>
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mostajs/nomenclature",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Référentiel de nomenclatures hiérarchiques (codes officiels) : charger, rechercher, valider et résoudre des codes liés par parentCode. Multi-schéma. Seeds livrés : 'naa-dz' (activités, CNRC/ONS), 'cim-10' (diagnostics, OMS/ICD-10), 'ccam' (actes médicaux). COMPOSE repository/orm/i18n. Couvre O4 Hadhinat + dossier médical (P3 Salsabil).",
|
|
5
|
+
"license": "AGPL-3.0-or-later",
|
|
6
|
+
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "src/index.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"src",
|
|
11
|
+
"llms.txt",
|
|
12
|
+
"README.md",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./src/index.js",
|
|
17
|
+
"./schemas": "./src/schemas.js",
|
|
18
|
+
"./seed-naa-dz": "./src/seed-naa-dz.js",
|
|
19
|
+
"./seed-cim10": "./src/seed-cim10.js",
|
|
20
|
+
"./seed-ccam": "./src/seed-ccam.js"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mostajs",
|
|
24
|
+
"nomenclature",
|
|
25
|
+
"naa",
|
|
26
|
+
"cnrc",
|
|
27
|
+
"ons",
|
|
28
|
+
"code-activite",
|
|
29
|
+
"nace",
|
|
30
|
+
"citi",
|
|
31
|
+
"cim-10",
|
|
32
|
+
"icd-10",
|
|
33
|
+
"ccam",
|
|
34
|
+
"oms",
|
|
35
|
+
"diagnostic",
|
|
36
|
+
"acte-medical",
|
|
37
|
+
"referentiel",
|
|
38
|
+
"hadhinat",
|
|
39
|
+
"salsabil"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"test": "node test-scripts/unit/nomenclature.test.mjs",
|
|
43
|
+
"example": "node examples/activites/run.mjs"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @mostajs/nomenclature — point d'entrée. Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
+
export { createNomenclature } from './nomenclature.js';
|
|
3
|
+
export { createMemoryRepositories } from './memory-repo.js';
|
|
4
|
+
export { NomenclatureCodeSchema } from './schemas.js';
|
|
5
|
+
export { NAA_DZ } from './seed-naa-dz.js';
|
|
6
|
+
export { CIM_10 } from './seed-cim10.js'; // schéma 'cim-10' (diagnostics — oncologie représentative)
|
|
7
|
+
export { CCAM } from './seed-ccam.js'; // schéma 'ccam' (actes/examens — imagerie/bio/anapath représentatifs)
|
|
8
|
+
export { HEALTH_SEEDS, ACTIVITY_SEEDS, ALL_SEEDS, BUILTIN_SCHEMES } from './seed-all.js'; // bundles par métier (santé injecte HEALTH_SEEDS)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @mostajs/nomenclature — repo in-memory pour tests/exemples (DB réelle via @mostajs/orm au déploiement). Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
+
function coll(){ const m=new Map(); return {
|
|
3
|
+
async create(d){ const id=d.id||globalThis.crypto.randomUUID(); const now=new Date(); const r={id,createdAt:now,updatedAt:now,...d}; m.set(id,r); return {...r}; },
|
|
4
|
+
async findById(id){ const r=m.get(id); return r?{...r}:null; },
|
|
5
|
+
async update(id,p){ const r=m.get(id); if(!r)return null; const x={...r,...p,updatedAt:new Date()}; m.set(id,x); return {...x}; },
|
|
6
|
+
async find(f=()=>true){ return [...m.values()].filter(f).map(r=>({...r})); } }; }
|
|
7
|
+
export function createMemoryRepositories(){ return { codes:coll() }; }
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// @mostajs/nomenclature — référentiel de nomenclatures hiérarchiques (codes d'activité officiels). Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
+
// Responsabilité UNIQUE : charger / rechercher / valider / résoudre des codes liés par parentCode. AUCUNE logique métier.
|
|
3
|
+
// COMPOSE par injection : repositories (persistance, @mostajs/orm en prod), i18n (libellés FR/AR), data-plug (import gros jeux côté app).
|
|
4
|
+
// Couvre le besoin O4 de Hadhinat (choix d'un code d'activité officiel) — mais transverse : CRM, billing, reporting, déclarations légales.
|
|
5
|
+
|
|
6
|
+
import { NAA_DZ } from './seed-naa-dz.js'; // défaut = domaine activités ; la santé injecte HEALTH_SEEDS (chacun son métier)
|
|
7
|
+
|
|
8
|
+
// Normalise un code : majuscules, sans espaces ni points (ex. '62.01' / ' 6201 ' → '6201').
|
|
9
|
+
const normCode = (c) => String(c ?? '').trim().toUpperCase().replace(/[\s.]/g, '');
|
|
10
|
+
// Replie un texte pour recherche insensible à la casse ET aux accents.
|
|
11
|
+
const fold = (s) => String(s ?? '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '');
|
|
12
|
+
const byCode = (a, b) => (a.level - b.level) || String(a.code).localeCompare(String(b.code));
|
|
13
|
+
const view = (r) => r && ({ scheme: r.scheme, code: r.code, label: r.label, labelAr: r.labelAr ?? null, parent: r.parentCode ?? null, parentCode: r.parentCode ?? null, level: r.level, active: r.active !== false });
|
|
14
|
+
|
|
15
|
+
export function createNomenclature({ repositories, dataset, defaultScheme = 'naa-dz', i18n } = {}) {
|
|
16
|
+
if (!repositories?.codes) throw new Error('createNomenclature: repositories.codes requis');
|
|
17
|
+
const { codes } = repositories;
|
|
18
|
+
|
|
19
|
+
// Seed : `dataset` injecté (chaque app son métier : santé → HEALTH_SEEDS, activités → naa-dz) sinon 'naa-dz' par défaut.
|
|
20
|
+
// Idempotent (skip si (scheme,code) déjà présent).
|
|
21
|
+
const seed = (dataset ?? NAA_DZ).map((r) => ({ scheme: r.scheme || defaultScheme, active: true, ...r, code: normCode(r.code), parentCode: r.parentCode == null ? null : normCode(r.parentCode) }));
|
|
22
|
+
const ready = (async () => {
|
|
23
|
+
for (const r of seed) {
|
|
24
|
+
const [exists] = await codes.find((x) => x.scheme === r.scheme && x.code === r.code);
|
|
25
|
+
if (!exists) await codes.create(r);
|
|
26
|
+
}
|
|
27
|
+
})();
|
|
28
|
+
|
|
29
|
+
const findOne = async (code, scheme) => { const [r] = await codes.find((x) => x.scheme === scheme && x.code === normCode(code)); return r || null; };
|
|
30
|
+
|
|
31
|
+
const api = {
|
|
32
|
+
ready,
|
|
33
|
+
codes: {
|
|
34
|
+
/** Recherche par préfixe de code OU plein texte (libellé FR/AR, sans accents). */
|
|
35
|
+
async search(q, { scheme = defaultScheme, limit = 20, level = null, activeOnly = true } = {}) {
|
|
36
|
+
await ready;
|
|
37
|
+
const needle = fold(q); const needleCode = normCode(q);
|
|
38
|
+
const rows = await codes.find((x) => x.scheme === scheme
|
|
39
|
+
&& (activeOnly ? x.active !== false : true)
|
|
40
|
+
&& (level == null || x.level === level)
|
|
41
|
+
&& (!q || x.code.startsWith(needleCode) || fold(x.label).includes(needle) || fold(x.labelAr).includes(needle)));
|
|
42
|
+
return rows.sort(byCode).slice(0, limit).map(view);
|
|
43
|
+
},
|
|
44
|
+
/** Détail d'un code. null si absent. */
|
|
45
|
+
async get(code, { scheme = defaultScheme } = {}) { await ready; return view(await findOne(code, scheme)); },
|
|
46
|
+
/** Sous-codes directs (navigation arborescente). */
|
|
47
|
+
async children(code, { scheme = defaultScheme } = {}) {
|
|
48
|
+
await ready; const p = normCode(code);
|
|
49
|
+
return (await codes.find((x) => x.scheme === scheme && x.parentCode === p)).sort(byCode).map(view);
|
|
50
|
+
},
|
|
51
|
+
/** Valide un code : { ok, normalized, label, level } | { ok:false, reason }. */
|
|
52
|
+
async validate(code, { scheme = defaultScheme } = {}) {
|
|
53
|
+
await ready; const r = await findOne(code, scheme);
|
|
54
|
+
if (!r) return { ok: false, reason: `code inconnu dans le schéma '${scheme}'` };
|
|
55
|
+
if (r.active === false) return { ok: false, reason: 'code inactif' };
|
|
56
|
+
return { ok: true, normalized: r.code, label: r.label, level: r.level };
|
|
57
|
+
},
|
|
58
|
+
/** Fil d'Ariane racine → feuille : [section, division, …, activité]. [] si code absent. */
|
|
59
|
+
async path(code, { scheme = defaultScheme } = {}) {
|
|
60
|
+
await ready; const out = []; let cur = await findOne(code, scheme); const guard = new Set();
|
|
61
|
+
while (cur && !guard.has(cur.code)) { guard.add(cur.code); out.push({ code: cur.code, label: cur.label, level: cur.level }); cur = cur.parentCode ? await findOne(cur.parentCode, scheme) : null; }
|
|
62
|
+
return out.reverse();
|
|
63
|
+
},
|
|
64
|
+
/** Libellé résolu (lang 'fr'|'ar') — via la donnée, sinon @mostajs/i18n si injecté. */
|
|
65
|
+
async label(code, { scheme = defaultScheme, lang = 'fr' } = {}) {
|
|
66
|
+
await ready; const r = await findOne(code, scheme); if (!r) return null;
|
|
67
|
+
if (lang === 'ar') return r.labelAr || i18n?.t?.(`nomenclature.${scheme}.${r.code}`, { lang: 'ar' }) || r.label;
|
|
68
|
+
return r.label;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
schemes: {
|
|
72
|
+
/** Schémas présents en base. */
|
|
73
|
+
async list() { await ready; return [...new Set((await codes.find()).map((x) => x.scheme))].sort(); },
|
|
74
|
+
/** Racines (level 1) d'un schéma — point d'entrée d'un arbre paresseux via codes.children(). */
|
|
75
|
+
async tree({ scheme = defaultScheme } = {}) {
|
|
76
|
+
await ready;
|
|
77
|
+
return (await codes.find((x) => x.scheme === scheme && (x.parentCode == null || x.level === 1))).sort(byCode).map(view);
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
repositories,
|
|
81
|
+
};
|
|
82
|
+
return api;
|
|
83
|
+
}
|
package/src/schemas.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @mostajs/nomenclature — schéma mince d'un code de nomenclature hiérarchique. Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
+
// Un référentiel = des codes liés par parentCode (section → division → groupe → classe → activité), réutilisable hors pépinière.
|
|
3
|
+
|
|
4
|
+
// Code de nomenclature normalisé (réf. CNRC / ONS NAA-NAP pour 'naa-dz'; extensible NAF/NACE).
|
|
5
|
+
export const NomenclatureCodeSchema = { name:'NomenclatureCode', collection:'codes', timestamps:true, fields:{
|
|
6
|
+
scheme:{type:'string',required:true,default:'naa-dz'}, // jeu de nomenclature ('naa-dz','naf-fr',…)
|
|
7
|
+
code:{type:'string',required:true}, // code dans le schéma (ex. '6201')
|
|
8
|
+
label:{type:'string',required:true}, // libellé (FR par défaut)
|
|
9
|
+
labelAr:{type:'string',default:null}, // libellé arabe (optionnel ; sinon via @mostajs/i18n)
|
|
10
|
+
parentCode:{type:'string',default:null}, // code parent (null = racine/section)
|
|
11
|
+
level:{type:'number',default:1}, // 1 section · 2 division · 3 groupe · 4 classe · 5 activité
|
|
12
|
+
active:{type:'boolean',default:true} },
|
|
13
|
+
indexes:[{fields:{scheme:'asc',code:'asc'},unique:true},{fields:{scheme:'asc',parentCode:'asc'}}] };
|
package/src/seed-all.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @mostajs/nomenclature — bundles de schémas par MÉTIER (chacun dans son domaine). Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
2
|
+
// Principe : chaque application seede LE(S) schéma(s) de SON métier — l'app santé injecte HEALTH_SEEDS,
|
|
3
|
+
// l'app activités garde le défaut 'naa-dz'. On NE mélange PAS les domaines par défaut.
|
|
4
|
+
// `ALL_SEEDS` reste disponible pour un cas (rare) où une app a réellement besoin de tous les schémas.
|
|
5
|
+
import { NAA_DZ } from './seed-naa-dz.js';
|
|
6
|
+
import { CIM_10 } from './seed-cim10.js';
|
|
7
|
+
import { CCAM } from './seed-ccam.js';
|
|
8
|
+
|
|
9
|
+
/** Registre nom→seed des schémas intégrés. */
|
|
10
|
+
export const BUILTIN_SCHEMES = { 'naa-dz': NAA_DZ, 'cim-10': CIM_10, 'ccam': CCAM };
|
|
11
|
+
|
|
12
|
+
/** Bundle métier ACTIVITÉS (à injecter dans une app d'activités, ou défaut implicite). */
|
|
13
|
+
export const ACTIVITY_SEEDS = [...NAA_DZ];
|
|
14
|
+
|
|
15
|
+
/** Bundle métier SANTÉ : diagnostics (cim-10) + actes/examens (ccam). À injecter dans l'app santé (P3 Salsabil). */
|
|
16
|
+
export const HEALTH_SEEDS = [...CIM_10, ...CCAM];
|
|
17
|
+
|
|
18
|
+
/** Tous les schémas (usage rare ; ne PAS utiliser comme défaut — chacun son métier). */
|
|
19
|
+
export const ALL_SEEDS = [...NAA_DZ, ...CIM_10, ...CCAM];
|
package/src/seed-ccam.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// @mostajs/nomenclature — seed 'ccam' : actes médicaux (logique CCAM) — imagerie / exploration / biologie / anapath.
|
|
2
|
+
// Author: Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
// Extrait REPRÉSENTATIF, codes ILLUSTRATIFS (préfixés par catégorie) pour composer @mostajs/medical-cases (type d'examen).
|
|
4
|
+
// En PRODUCTION : charger les référentiels OFFICIELS via `dataset` injecté — CCAM (actes techniques),
|
|
5
|
+
// NABM (biologie médicale), ADICAP (anatomopathologie). Ici : catalogue minimal couvrant la spec Salsabil.
|
|
6
|
+
// Niveaux : 1 catégorie · 2 acte.
|
|
7
|
+
|
|
8
|
+
export const CCAM = [
|
|
9
|
+
// ── Imagerie médicale ──
|
|
10
|
+
{ scheme: 'ccam', code: 'IMG', label: 'Imagerie médicale', labelAr: 'التصوير الطبي', parentCode: null, level: 1 },
|
|
11
|
+
{ scheme: 'ccam', code: 'IMG-TDM', label: 'Tomodensitométrie (Scanner / TDM)', parentCode: 'IMG', level: 2 },
|
|
12
|
+
{ scheme: 'ccam', code: 'IMG-IRM', label: 'Imagerie par résonance magnétique (IRM)', parentCode: 'IMG', level: 2 },
|
|
13
|
+
{ scheme: 'ccam', code: 'IMG-ECHO', label: 'Échographie', parentCode: 'IMG', level: 2 },
|
|
14
|
+
{ scheme: 'ccam', code: 'IMG-TEP', label: 'Tomographie par émission de positons (TEP-Scan)', parentCode: 'IMG', level: 2 },
|
|
15
|
+
{ scheme: 'ccam', code: 'IMG-DMO', label: 'Ostéodensitométrie (DMO)', parentCode: 'IMG', level: 2 },
|
|
16
|
+
|
|
17
|
+
// ── Examens spécialisés ──
|
|
18
|
+
{ scheme: 'ccam', code: 'EXP', label: 'Examens spécialisés', parentCode: null, level: 1 },
|
|
19
|
+
{ scheme: 'ccam', code: 'EXP-CORO', label: 'Coroscanner (angioscanner coronaire)', parentCode: 'EXP', level: 2 },
|
|
20
|
+
{ scheme: 'ccam', code: 'EXP-SCINT', label: 'Scintigraphie osseuse', parentCode: 'EXP', level: 2 },
|
|
21
|
+
|
|
22
|
+
// ── Biologie médicale (réf. officielle : NABM) ──
|
|
23
|
+
{ scheme: 'ccam', code: 'BIO', label: 'Biologie médicale (analyses)', labelAr: 'التحاليل الطبية', parentCode: null, level: 1 },
|
|
24
|
+
{ scheme: 'ccam', code: 'BIO-NFS', label: 'Numération formule sanguine (NFS)', parentCode: 'BIO', level: 2 },
|
|
25
|
+
{ scheme: 'ccam', code: 'BIO-MARQ', label: 'Marqueurs tumoraux', parentCode: 'BIO', level: 2 },
|
|
26
|
+
{ scheme: 'ccam', code: 'BIO-DIV', label: 'Analyses médicales diverses', parentCode: 'BIO', level: 2 },
|
|
27
|
+
|
|
28
|
+
// ── Anatomopathologie (réf. officielle : ADICAP) ──
|
|
29
|
+
{ scheme: 'ccam', code: 'ANP', label: 'Anatomopathologie', parentCode: null, level: 1 },
|
|
30
|
+
{ scheme: 'ccam', code: 'ANP-HISTO', label: 'Examen histologique (ANAPATH)', parentCode: 'ANP', level: 2 },
|
|
31
|
+
{ scheme: 'ccam', code: 'ANP-CYTO', label: 'Examen cytologique', parentCode: 'ANP', level: 2 },
|
|
32
|
+
];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// @mostajs/nomenclature — seed 'cim-10' : Classification Internationale des Maladies, 10ᵉ révision (OMS / ICD-10).
|
|
2
|
+
// Author: Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
3
|
+
// Extrait REPRÉSENTATIF (oncologie : tumeurs malignes C00–C97) pour composer @mostajs/medical-cases (diagnostic).
|
|
4
|
+
// PAS exhaustif : charger le référentiel CIM-10 complet via `dataset` injecté en prod (createNomenclature).
|
|
5
|
+
// NB : le module normalise les codes (majuscules, SANS points) → 'C50.9' est stocké 'C509' ; la forme canonique
|
|
6
|
+
// pointée figure dans le libellé. Niveaux : 1 racine · 2 bloc (plage) · 3 catégorie (3 car.) · 4 sous-catégorie.
|
|
7
|
+
|
|
8
|
+
export const CIM_10 = [
|
|
9
|
+
{ scheme: 'cim-10', code: 'C00-C97', label: 'Tumeurs malignes', labelAr: 'الأورام الخبيثة', parentCode: null, level: 1 },
|
|
10
|
+
|
|
11
|
+
// ── Blocs (plages) ──
|
|
12
|
+
{ scheme: 'cim-10', code: 'C00-C14', label: 'Lèvre, cavité buccale et pharynx', parentCode: 'C00-C97', level: 2 },
|
|
13
|
+
{ scheme: 'cim-10', code: 'C15-C26', label: 'Organes digestifs', parentCode: 'C00-C97', level: 2 },
|
|
14
|
+
{ scheme: 'cim-10', code: 'C30-C39', label: 'Organes respiratoires et intrathoraciques', parentCode: 'C00-C97', level: 2 },
|
|
15
|
+
{ scheme: 'cim-10', code: 'C40-C41', label: 'Os et cartilage articulaire', parentCode: 'C00-C97', level: 2 },
|
|
16
|
+
{ scheme: 'cim-10', code: 'C43-C44', label: 'Mélanome et autres tumeurs malignes de la peau', parentCode: 'C00-C97', level: 2 },
|
|
17
|
+
{ scheme: 'cim-10', code: 'C50', label: 'Tumeur maligne du sein', labelAr: 'سرطان الثدي', parentCode: 'C00-C97', level: 2 },
|
|
18
|
+
{ scheme: 'cim-10', code: 'C51-C58', label: 'Organes génitaux de la femme', parentCode: 'C00-C97', level: 2 },
|
|
19
|
+
{ scheme: 'cim-10', code: 'C60-C63', label: 'Organes génitaux de l’homme', parentCode: 'C00-C97', level: 2 },
|
|
20
|
+
{ scheme: 'cim-10', code: 'C64-C68', label: 'Voies urinaires', parentCode: 'C00-C97', level: 2 },
|
|
21
|
+
{ scheme: 'cim-10', code: 'C73-C75', label: 'Thyroïde et autres glandes endocrines', parentCode: 'C00-C97', level: 2 },
|
|
22
|
+
{ scheme: 'cim-10', code: 'C81-C96', label: 'Tissus lymphoïde, hématopoïétique et apparentés', parentCode: 'C00-C97', level: 2 },
|
|
23
|
+
|
|
24
|
+
// ── Catégories (3 caractères) ──
|
|
25
|
+
{ scheme: 'cim-10', code: 'C16', label: 'Tumeur maligne de l’estomac', parentCode: 'C15-C26', level: 3 },
|
|
26
|
+
{ scheme: 'cim-10', code: 'C18', label: 'Tumeur maligne du côlon', parentCode: 'C15-C26', level: 3 },
|
|
27
|
+
{ scheme: 'cim-10', code: 'C22', label: 'Tumeur maligne du foie et des voies biliaires intrahépatiques', parentCode: 'C15-C26', level: 3 },
|
|
28
|
+
{ scheme: 'cim-10', code: 'C25', label: 'Tumeur maligne du pancréas', parentCode: 'C15-C26', level: 3 },
|
|
29
|
+
{ scheme: 'cim-10', code: 'C34', label: 'Tumeur maligne des bronches et du poumon', labelAr: 'سرطان الرئة', parentCode: 'C30-C39', level: 3 },
|
|
30
|
+
{ scheme: 'cim-10', code: 'C53', label: 'Tumeur maligne du col de l’utérus', parentCode: 'C51-C58', level: 3 },
|
|
31
|
+
{ scheme: 'cim-10', code: 'C56', label: 'Tumeur maligne de l’ovaire', parentCode: 'C51-C58', level: 3 },
|
|
32
|
+
{ scheme: 'cim-10', code: 'C61', label: 'Tumeur maligne de la prostate', labelAr: 'سرطان البروستاتا', parentCode: 'C60-C63', level: 3 },
|
|
33
|
+
{ scheme: 'cim-10', code: 'C64', label: 'Tumeur maligne du rein, sauf bassinet', parentCode: 'C64-C68', level: 3 },
|
|
34
|
+
{ scheme: 'cim-10', code: 'C67', label: 'Tumeur maligne de la vessie', parentCode: 'C64-C68', level: 3 },
|
|
35
|
+
{ scheme: 'cim-10', code: 'C73', label: 'Tumeur maligne de la thyroïde', parentCode: 'C73-C75', level: 3 },
|
|
36
|
+
{ scheme: 'cim-10', code: 'C81', label: 'Maladie de Hodgkin (lymphome hodgkinien)', parentCode: 'C81-C96', level: 3 },
|
|
37
|
+
{ scheme: 'cim-10', code: 'C85', label: 'Lymphomes non hodgkiniens, autres et non précisés', parentCode: 'C81-C96', level: 3 },
|
|
38
|
+
{ scheme: 'cim-10', code: 'C90', label: 'Myélome multiple et tumeurs malignes à plasmocytes', parentCode: 'C81-C96', level: 3 },
|
|
39
|
+
{ scheme: 'cim-10', code: 'C91', label: 'Leucémie lymphoïde', parentCode: 'C81-C96', level: 3 },
|
|
40
|
+
{ scheme: 'cim-10', code: 'C92', label: 'Leucémie myéloïde', parentCode: 'C81-C96', level: 3 },
|
|
41
|
+
|
|
42
|
+
// ── Sous-catégories (.9 = sans précision) — code dédoté par le module (C50.9 → C509) ──
|
|
43
|
+
{ scheme: 'cim-10', code: 'C50.9', label: 'Sein, sans précision (C50.9)', parentCode: 'C50', level: 3 },
|
|
44
|
+
{ scheme: 'cim-10', code: 'C34.9', label: 'Bronche ou poumon, sans précision (C34.9)', parentCode: 'C34', level: 4 },
|
|
45
|
+
{ scheme: 'cim-10', code: 'C18.9', label: 'Côlon, sans précision (C18.9)', parentCode: 'C18', level: 4 },
|
|
46
|
+
{ scheme: 'cim-10', code: 'C61.9', label: 'Prostate, sans précision (C61.9)', parentCode: 'C61', level: 4 },
|
|
47
|
+
];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// @mostajs/nomenclature — seed 'naa-dz' : Nomenclature Algérienne des Activités (alignée CITI Rev.4 / NACE).
|
|
2
|
+
// Réf. : CNRC (Centre National du Registre du Commerce) & ONS (NAA-NAP). Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
3
|
+
// Extrait REPRÉSENTATIF (pas exhaustif) : breadth multi-sections + depth complète sur la branche 62 (informatique)
|
|
4
|
+
// jusqu'au niveau 5 (activité nationale) pour démontrer path()/children(). Étendre par `dataset` injecté en prod.
|
|
5
|
+
// Niveaux : 1 section (lettre) · 2 division (2 ch.) · 3 groupe (3) · 4 classe (4) · 5 activité (5).
|
|
6
|
+
|
|
7
|
+
export const NAA_DZ = [
|
|
8
|
+
// ── Section A — Agriculture, sylviculture et pêche ──
|
|
9
|
+
{ code:'A', label:'Agriculture, sylviculture et pêche', labelAr:'الفلاحة والغابات والصيد', parentCode:null, level:1 },
|
|
10
|
+
{ code:'01', label:'Culture et production animale, chasse', parentCode:'A', level:2 },
|
|
11
|
+
{ code:'011', label:'Cultures non permanentes', parentCode:'01', level:3 },
|
|
12
|
+
{ code:'0111', label:'Culture de céréales et de légumineuses', parentCode:'011', level:4 },
|
|
13
|
+
{ code:'0113', label:'Culture de légumes et de melons', parentCode:'011', level:4 },
|
|
14
|
+
{ code:'03', label:'Pêche et aquaculture', parentCode:'A', level:2 },
|
|
15
|
+
{ code:'032', label:'Aquaculture', parentCode:'03', level:3 },
|
|
16
|
+
|
|
17
|
+
// ── Section C — Industrie manufacturière ──
|
|
18
|
+
{ code:'C', label:'Industrie manufacturière', labelAr:'الصناعة التحويلية', parentCode:null, level:1 },
|
|
19
|
+
{ code:'10', label:'Industries alimentaires', parentCode:'C', level:2 },
|
|
20
|
+
{ code:'107', label:'Fabrication de produits de boulangerie et pâtes', parentCode:'10', level:3 },
|
|
21
|
+
{ code:'1071', label:'Fabrication de pain et de pâtisserie fraîche', parentCode:'107', level:4 },
|
|
22
|
+
{ code:'13', label:'Fabrication de textiles', parentCode:'C', level:2 },
|
|
23
|
+
|
|
24
|
+
// ── Section F — Construction ──
|
|
25
|
+
{ code:'F', label:'Construction', labelAr:'البناء والأشغال العمومية', parentCode:null, level:1 },
|
|
26
|
+
{ code:'41', label:'Construction de bâtiments', parentCode:'F', level:2 },
|
|
27
|
+
{ code:'412', label:'Construction de bâtiments résidentiels et non résidentiels', parentCode:'41', level:3 },
|
|
28
|
+
{ code:'4120', label:'Construction de bâtiments résidentiels et non résidentiels', parentCode:'412', level:4 },
|
|
29
|
+
{ code:'43', label:'Travaux de construction spécialisés', parentCode:'F', level:2 },
|
|
30
|
+
|
|
31
|
+
// ── Section G — Commerce; réparation d'automobiles et de motocycles ──
|
|
32
|
+
{ code:'G', label:'Commerce; réparation d\'automobiles et de motocycles', labelAr:'التجارة وإصلاح السيارات', parentCode:null, level:1 },
|
|
33
|
+
{ code:'47', label:'Commerce de détail, sauf automobiles et motocycles', parentCode:'G', level:2 },
|
|
34
|
+
{ code:'479', label:'Commerce de détail hors magasin, éventaires ou marchés', parentCode:'47', level:3 },
|
|
35
|
+
{ code:'4791', label:'Vente à distance (commerce électronique)', labelAr:'البيع عن بعد (التجارة الإلكترونية)', parentCode:'479', level:4 },
|
|
36
|
+
|
|
37
|
+
// ── Section I — Hébergement et restauration ──
|
|
38
|
+
{ code:'I', label:'Hébergement et restauration', labelAr:'الإيواء والإطعام', parentCode:null, level:1 },
|
|
39
|
+
{ code:'55', label:'Hébergement', parentCode:'I', level:2 },
|
|
40
|
+
{ code:'56', label:'Restauration', parentCode:'I', level:2 },
|
|
41
|
+
{ code:'561', label:'Restaurants et services de restauration mobile', parentCode:'56', level:3 },
|
|
42
|
+
{ code:'5610', label:'Restauration traditionnelle', parentCode:'561', level:4 },
|
|
43
|
+
|
|
44
|
+
// ── Section J — Information et communication ──
|
|
45
|
+
{ code:'J', label:'Information et communication', labelAr:'الإعلام والاتصال', parentCode:null, level:1 },
|
|
46
|
+
{ code:'58', label:'Édition', parentCode:'J', level:2 },
|
|
47
|
+
{ code:'582', label:'Édition de logiciels', parentCode:'58', level:3 },
|
|
48
|
+
{ code:'5829', label:'Édition d\'autres logiciels', parentCode:'582', level:4 },
|
|
49
|
+
{ code:'61', label:'Télécommunications', labelAr:'الاتصالات السلكية واللاسلكية', parentCode:'J', level:2 },
|
|
50
|
+
{ code:'62', label:'Programmation, conseil et autres activités informatiques', labelAr:'البرمجة والاستشارة والأنشطة المعلوماتية', parentCode:'J', level:2 },
|
|
51
|
+
{ code:'620', label:'Programmation, conseil et autres activités informatiques', parentCode:'62', level:3 },
|
|
52
|
+
{ code:'6201', label:'Programmation informatique', labelAr:'البرمجة المعلوماتية', parentCode:'620', level:4 },
|
|
53
|
+
{ code:'62011', label:'Développement de logiciels sur mesure', labelAr:'تطوير البرمجيات حسب الطلب', parentCode:'6201', level:5 },
|
|
54
|
+
{ code:'62012', label:'Édition de logiciels applicatifs et services SaaS', labelAr:'نشر البرمجيات التطبيقية وخدمات SaaS', parentCode:'6201', level:5 },
|
|
55
|
+
{ code:'6202', label:'Conseil informatique', labelAr:'الاستشارة المعلوماتية', parentCode:'620', level:4 },
|
|
56
|
+
{ code:'6203', label:'Gestion d\'installations informatiques', parentCode:'620', level:4 },
|
|
57
|
+
{ code:'6209', label:'Autres activités informatiques', parentCode:'620', level:4 },
|
|
58
|
+
{ code:'63', label:'Services d\'information', parentCode:'J', level:2 },
|
|
59
|
+
{ code:'631', label:'Traitement de données, hébergement et portails', parentCode:'63', level:3 },
|
|
60
|
+
{ code:'6311', label:'Traitement de données, hébergement et activités connexes', labelAr:'معالجة المعطيات والاستضافة', parentCode:'631', level:4 },
|
|
61
|
+
{ code:'6312', label:'Portails internet', parentCode:'631', level:4 },
|
|
62
|
+
|
|
63
|
+
// ── Section M — Activités spécialisées, scientifiques et techniques ──
|
|
64
|
+
{ code:'M', label:'Activités spécialisées, scientifiques et techniques', labelAr:'الأنشطة المتخصصة والعلمية والتقنية', parentCode:null, level:1 },
|
|
65
|
+
{ code:'69', label:'Activités juridiques et comptables', parentCode:'M', level:2 },
|
|
66
|
+
{ code:'691', label:'Activités juridiques', parentCode:'69', level:3 },
|
|
67
|
+
{ code:'692', label:'Activités comptables, de gestion et d\'audit', parentCode:'69', level:3 },
|
|
68
|
+
{ code:'70', label:'Activités des sièges sociaux; conseil de gestion', parentCode:'M', level:2 },
|
|
69
|
+
{ code:'702', label:'Conseil de gestion', parentCode:'70', level:3 },
|
|
70
|
+
{ code:'7022', label:'Conseil pour les affaires et autres conseils de gestion', labelAr:'استشارات في الأعمال والتسيير', parentCode:'702', level:4 },
|
|
71
|
+
{ code:'72', label:'Recherche-développement scientifique', parentCode:'M', level:2 },
|
|
72
|
+
{ code:'73', label:'Publicité et études de marché', parentCode:'M', level:2 },
|
|
73
|
+
{ code:'731', label:'Publicité', parentCode:'73', level:3 },
|
|
74
|
+
{ code:'7311', label:'Activités des agences de publicité', labelAr:'أنشطة وكالات الإشهار', parentCode:'731', level:4 },
|
|
75
|
+
|
|
76
|
+
// ── Section P — Enseignement ──
|
|
77
|
+
{ code:'P', label:'Enseignement', labelAr:'التعليم', parentCode:null, level:1 },
|
|
78
|
+
{ code:'85', label:'Enseignement', parentCode:'P', level:2 },
|
|
79
|
+
{ code:'855', label:'Autres activités d\'enseignement', parentCode:'85', level:3 },
|
|
80
|
+
{ code:'8559', label:'Enseignements divers (formation continue)', labelAr:'التكوين المتواصل', parentCode:'855', level:4 },
|
|
81
|
+
|
|
82
|
+
// ── Section Q — Santé humaine et action sociale ──
|
|
83
|
+
{ code:'Q', label:'Santé humaine et action sociale', labelAr:'الصحة والعمل الاجتماعي', parentCode:null, level:1 },
|
|
84
|
+
{ code:'86', label:'Activités pour la santé humaine', parentCode:'Q', level:2 },
|
|
85
|
+
{ code:'862', label:'Activités des médecins et des dentistes', parentCode:'86', level:3 },
|
|
86
|
+
];
|