# Marque blanche : créer et faire vivre une instance

:::tip{title="En bref"}
une instance = un fichier `instances/<id>/research.config.ts`, deux logos, une entrée dans deux registres. Tout le reste (thème, libellés, navigation, données, recherche) en découle. Décision : [ADR 007](/decisions/instances-marque-blanche).
:::

## Ce que pilote la configuration

| Bloc           | Effet dans le site                                                                                                                                             |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `site`         | Nom, accroche et introduction (fr/en), URL canonique, langues publiées (`locales`), éditeur (©)                                                                |
| `brand.logo`   | Logo clair (en-tête) et foncé (pied de page)                                                                                                                   |
| `brand.colors` | 4 couleurs → thème Mantine calculé : `brand` (boutons, liens, titres de section), `accent` (surtitres, badges), `ink` (titres, pied de page), `surface` (fond) |
| `brand.fonts`  | Polices du texte et des titres (à charger dans `src/app/globals.css`)                                                                                          |
| `perimeter`    | Identifiants dans chaque source ; annuaire institutionnel (`directory`) et liste maître (`masterList`)                                                         |
| `groups`       | Libellé du niveau intermédiaire (« Graduate School », « Pôle disciplinaire »), liste, règles de rattachement                                                   |
| `entities`     | Libellés des types (« Laboratoires », « Unités de recherche ») ; navigation et pages                                                                           |
| `people`       | Règle de publication des personnes (ADR 010)                                                                                                                   |
| `themes`       | Thématiques transversales et leurs règles                                                                                                                      |
| `sources`      | Sources actives, rôle et priorité                                                                                                                              |
| `search`       | Moteur et types indexés                                                                                                                                        |

## Créer une instance (exemple : `ugA`)

1. **Identifiants** : chercher l'établissement dans ROR, scanR, OpenAlex, HAL (collection et structure AureHAL). Les requêtes utilisées pour Paris 1 sont dans [sources.md](/donnees/sources).
2. **Configuration** : copier `instances/paris1/research.config.ts` vers `instances/<id>/`, changer `id`, `site`, `brand`, `perimeter`, `groups`, `themes`.
3. **Logos** : `public/brand/<id>/logo.svg` et `logo-white.svg`.
4. **Registres** : ajouter l'instance dans `src/config/index.ts` (`INSTANCES`) et un port dans `scripts/instance.mjs` (`PORTS`), puis les scripts `dev:<id>`, `build:<id>`, `start:<id>` dans `package.json`.
5. **Polices** : si elles diffèrent, ajouter le paquet `@fontsource/…` et ses `@import` dans `globals.css`.
6. **Données** :
   ```bash
   pnpm data:probe --instance <id>      # ce que les sources savent du périmètre (2 min)
   pnpm data:extract --instance <id>    # moisson complète
   pnpm data:build --instance <id>      # publication
   pnpm dev:<id>
   ```
7. **Contrôle** : `pnpm test` (le test `config.test.ts` vérifie que chaque instance est valide et a un ROR distinct), puis lecture de `/a-propos-des-donnees`.

## Brancher l'annuaire de l'établissement

Le parseur générique lit deux gabarits courants ([ADR 013](/decisions/liste-officielle-et-annuaire-generique)) :

```ts
// Une page par structure (Paris-Saclay)
directory: {
  url: 'https://www.universite-paris-saclay.fr/laboratoires',
  mode: 'pages',
  pagePattern: '^/laboratoires/.+',          // chemins des fiches
  labels: { supervisors: 'Tutelles et partenaires', website: 'Site web du laboratoire',
            description: 'Présentation du laboratoire' },
},
// Une page liste avec une carte par unité (Paris 1)
directory: {
  url: 'https://recherche.pantheonsorbonne.fr/structures-de-recherche/unites-de-recherche',
  mode: 'cards',
  cardMarker: 'class="sm-teaser"',           // fragment HTML qui ouvre chaque carte
  useSitemap: false,
},
masterList: 'directory',                       // l'annuaire devient la liste officielle
```

Pour vérifier un nouveau gabarit : `pnpm data:extract --instance <id> --source annuaire`, puis lire `data/raw/<id>/annuaire/laboratories.ndjson` et le rapport `data/coverage/<id>/qualite.md`.

## Langues

Français sans préfixe, anglais sous `/en` ([ADR 012](/decisions/version-anglaise)). Chaque libellé `Localized` de la configuration prend un champ `en`. Les textes d'interface sont dans `src/i18n/messages.ts`.

## Ce qui n'est pas encore configurable

- **Contenu juridique** des pages légales : texte générique au nom de l'éditeur, à remplacer par instance.
- **Segments d'URL** : en français dans les deux langues (`/en/structures`, `/en/chercheurs`).

## Deux instances livrées

|                           | Saclay                            | Paris 1 |
| ------------------------- | --------------------------------- | ------- |
| Port local                | 3000                              | 3010    |
| Pages générées            | 23 444                            | 4 802   |
| Pages indexées (Pagefind) | 12 209                            | 2 417   |
| Génération des pages      | 63 s (build complet : 2 min 23 s) | 7 s     |

## Pourquoi ne pas reprendre scanR tel quel

Le code de scanR est public ([dataesr/scanr-ui](https://github.com/dataesr/scanr-ui), licence MIT, mis à jour le 23/10/2026). Ce qu'on y lit :

| Aspect           | scanR                                                                                                                         | Conséquence pour nous                                                                                               |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Rendu            | Application React + Vite rendue dans le navigateur                                                                            | Peu adapté au référencement d'une vitrine ; on garde Next.js (SSR/ISR)                                              |
| Données          | Index Elasticsearch du MESR (`scanr-organizations`, `-persons`, `-projects`, `-publications`, `-patents`), via un proxy nginx | On **réutilise ces données** (sonde `scanr`), pas l'infrastructure                                                  |
| Personnalisation | Variables `VITE_*` (nom, bandeau), DSFR via `@dataesr/dsfr-plus`                                                              | Trop limité pour une charte d'établissement ; d'où `research.config.ts`                                             |
| Hiérarchie       | Liens tutelle/participant du RNSR, à plat                                                                                     | Notre valeur propre : Graduate School, UFR, laboratoire                                                             |
| « Studio »       | Un scanR local fourni par le MESR pour une collection HAL                                                                     | Alternative à évaluer en premier : si la vitrine se réduit à cela, demander le Studio (cf. audit, _Valeur ajoutée_) |

À reprendre de scanR : la **typologie des entités** et des identifiants, la logique **une page par entité** avec ses liens, le **découpage des index par type**, et la liste des sources qu'il agrège.
