Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ae300d7
chore(i18n): corrige la traduction des blocs de citation
liliced Sep 29, 2025
b9685c3
refactor(imposition): déplace les règles entreprise . chiffre d'affai…
liliced Sep 29, 2025
21af9b3
fix(entreprise): Change la date limite d'exercice de 2018 à 2022
liliced Sep 29, 2025
0a1365a
docs(imposition): ajoute un lien à la notification sur le report de d…
liliced Sep 29, 2025
8a8b896
refactor(imposition): déplace l'attribut description
liliced Sep 29, 2025
4e5cd5b
feat(imposition): ajout de la règle incluant la contribution sociale
liliced Sep 29, 2025
de4bc04
fix(is): correction du calcul de la durée de l'exercice
liliced Oct 2, 2025
f3a93f6
tests(is): mise à jour des tests
liliced Oct 2, 2025
597219e
refactor(imposition): réorganisation du calcul de l'IS et suppression…
liliced Sep 29, 2025
76f72e5
docs: ajoute le pattern Compound Components
JalilArfaoui Oct 2, 2025
e68157a
chore(modele-social): migration 'une possibilité'
liliced Oct 9, 2025
4aa3c6c
chore(i18n): corrige la traduction des blocs de citation
liliced Sep 29, 2025
5883a7b
refactor(imposition): déplace les règles entreprise . chiffre d'affai…
liliced Sep 29, 2025
4387a46
fix(entreprise): Change la date limite d'exercice de 2018 à 2022
liliced Sep 29, 2025
ea0a4eb
docs(imposition): ajoute un lien à la notification sur le report de d…
liliced Sep 29, 2025
7132efc
refactor(imposition): déplace l'attribut description
liliced Sep 29, 2025
13a266e
feat(imposition): ajout de la règle incluant la contribution sociale
liliced Sep 29, 2025
2bddc69
fix(is): correction du calcul de la durée de l'exercice
liliced Oct 2, 2025
8eb1b24
tests(is): mise à jour des tests
liliced Oct 2, 2025
c31a13b
refactor(imposition): réorganisation du calcul de l'IS et suppression…
liliced Sep 29, 2025
03892c8
docs: ajoute le pattern Compound Components
JalilArfaoui Oct 2, 2025
93bc658
chore(modele-social): migration 'une possibilité'
liliced Oct 9, 2025
b74381d
fix(une possibilité): masque les options non applicables pour UnePoss…
liliced Oct 14, 2025
4f71afe
feat(cessation activité): reformulation de la question sur la cessati…
liliced Oct 16, 2025
d2b86d1
fix(médecin): correction du taux maladie pour médecins S2
liliced Oct 17, 2025
96d252e
fix(apprentis): exonération de CSG-CRDS pour les apprentis
liliced Oct 17, 2025
c4c78a5
feat(apprentis): ajoute l'exonération de taxe sur les salaires des ap…
liliced Oct 17, 2025
450fb55
tests(apprentis): met à jour les tests
liliced Oct 17, 2025
0982316
fix(pamc): masque les cotisations forfaitaires en cas de résidence fi…
liliced Oct 17, 2025
2f37ba2
chore(modele-social): v9.0.0
liliced Oct 20, 2025
c81cc80
Merge branch 'main' of https://github.com/betagouv/mon-entreprise
ThomasKsK Dec 8, 2025
194c656
feat(og): refresh Open Graph images and add Twitter cards
idel07 Jan 19, 2026
895dcc4
refactor(textfield): exposer une API de theming (CSS vars) et supprim…
idel07 Jan 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,20 @@ Nous utilisons :
- [Prettier](https://prettier.io/) pour formater le code source, l'idéal est de configurer votre éditeur de texte pour que les fichiers soit formatés automatiquement quand vous sauvegardez un fichier. Si vous utilisez [VS Code](https://code.visualstudio.com/) cette configuration est automatique.
- [Publicodes](https://publi.codes) pour la gestion des règles métiers
- [React](https://reactjs.org) pour la gestion de l'interface utilisateur
- [Redux](https://redux.js.org) pour gérer le state de l'application côté client
- [Redux](https://redux.js.org) pour gérer le "state" de l'application côté client
- [TypeScript](https://www.typescriptlang.org) pour ajouter un système de typage à notre code JavaScript. Le typage n'est pas utilisé partout et il n'est pas obligatoire de le prendre en compte pour contribuer.
- [ViteJS](https://vitejs.dev) pour le bundling et le serveur de développement
- [ViteJS](https://vitejs.dev) pour le "bundling" et le serveur de développement
- [Vitest](https://vitest.dev) et [Cypress](https://www.cypress.io) pour l'execution des tests. Plus d'informations dans la section consacrée aux tests.
- [Yarn](https://yarnpkg.com) pour la gestion des dépendances (à la place de NPM qui est souvent utilisé dans les applications JavaScript)

### Patterns et bonnes pratiques

#### Compound Components

Pour créer des composants React réutilisables et composables, nous privilégions le **pattern Compound Components**. Ce pattern permet de créer des APIs de composants flexibles où les sous-composants sont exposés comme propriétés du composant principal, offrant une composition déclarative tout en gardant le contrôle sur le rendu final.

Pour plus de détails sur ce pattern, consultez l'[ADR sur les Compound Components](./adr/ADR-2025-10-02-compound-components.md).

### Tests

#### Vérification syntaxique :
Expand Down
181 changes: 181 additions & 0 deletions adr/ADR-2025-10-02-compound-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# ADR : Pattern Compound Components pour les composants React

## Date
2025-10-02

## Contexte

On refactorise le simulateur location-de-meublé pour passer d'une interface séquentielle à une interface de comparaison en colonnes. On veut créer des composants réutilisables qui soient flexibles tout en gardant le contrôle sur le rendu.

## Problématique

Actuellement, nos composants de comparaison ressemblent à ça :

```tsx
// Dans DetailsRowCards.tsx - lourd et couplé
<StatusCard
statut={sameValueOptions.map(({ name }) => name)}
footerContent={footer?.(statusObject.engine)}
isBestOption={bestOptionValue === statusObject.name}
>
<StyledBody as="div">
<StyledDiv>
<span>
<Value expression={expressionOrDottedName} engine={statusObject.engine} />
{label && ' '}
{label && label}
</span>
<StyledRuleLink documentationPath={statusObject.name} dottedName={dottedName}>
<HelpIcon />
</StyledRuleLink>
{warning?.(statusObject.engine)}
</StyledDiv>
<Precisions>
<Value expression={evolutionDottedName} engine={statusObject.engine} />
{evolutionLabel}
</Precisions>
</StyledBody>
</StatusCard>
```

**Problèmes** :
- Plein de `StyledXXX` partout qui polluent le code
- Logique de layout mélangée avec le contenu
- Difficile de réutiliser dans un autre contexte
- Props `footerContent`, `isBestOption` spécifiques à un cas d'usage
- Impossible de composer librement le contenu

Comment créer des composants qui permettent de faire ça de manière plus propre et flexible ?

## Solution : Compound Components

On expose des sous-composants comme propriétés du composant principal :

```tsx
<CarteComparaison meilleureOption>
<CarteComparaison.Étiquettes>
<RégimeTag régime="RG" />
</CarteComparaison.Étiquettes>
<CarteComparaison.Contenu>
<span>1 800€</span>
</CarteComparaison.Contenu>
</CarteComparaison>
```

Le composant parent peut alors organiser les enfants comme il veut :

```tsx
const CarteComparaison = ({ children, meilleureOption }) => {
// On récupère les sous-composants
const étiquettes = React.Children.toArray(children).find(
child => child.type === CarteComparaison.Étiquettes
)
const contenu = React.Children.toArray(children).find(
child => child.type === CarteComparaison.Contenu
)

// On contrôle complètement le layout
return (
<Card>
<Header>{étiquettes}</Header>
<MainContent highlighted={meilleureOption}>
{contenu}
</MainContent>
</Card>
)
}
```

## Avantages

✅ **API intuitive** : Ça ressemble à du HTML, facile à comprendre
✅ **Flexibilité** : L'utilisateur met ce qu'il veut dans chaque section
✅ **Contrôle du layout** : On garde la main sur l'organisation finale
✅ **Pas de StyledBody partout** : Les styles restent dans le composant
✅ **Facile à étendre** : Ajouter un nouveau sous-composant ne casse rien

## Inconvénients

❌ **Plus de code initial** : Un peu plus long à mettre en place
❌ **React.Children** : Peut être moins performant avec beaucoup d'enfants

## Alternatives qu'on a écartées

### Option 1 : StyledBody partout (ce qu'on fait actuellement)

```tsx
<StatusCard>
<StyledBody>
<StyledTitle>1 800€</StyledTitle>
<StyledSubtitle>par mois</StyledSubtitle>
</StyledBody>
</StatusCard>
```

**Problème** : On se retrouve avec des `StyledXXX` partout, les styles sont éparpillés, et c'est dur de maintenir une cohérence visuelle.

### Option 2 : Props monolithiques

```tsx
<CarteComparaison
étiquettes={<RégimeTag régime="RG" />}
contenu="1 800€"
sousTitre="par mois"
/>
```

**Problème** : Moins flexible, on doit prévoir toutes les props possibles à l'avance, et l'API devient vite énorme.

### Option 3 : Configuration par objet

```tsx
<CarteComparaison
config={{
étiquettes: ["RG", "AE"],
montant: 1800,
unité: "€/mois"
}}
/>
```

**Problème** : Trop rigide, on perd la composabilité React, et on ne peut pas mettre de composants custom.

## Quand utiliser ce pattern ?

👍 **À utiliser pour** :
- Composants complexes (cartes de comparaison, formulaires multi-sections)
- Quand on veut offrir de la flexibilité tout en gardant le contrôle
- Pour éviter la multiplication des `StyledXXX`

👎 **À éviter pour** :
- Composants simples (un bouton, un input basique)
- Quand une simple prop suffit

## Exemple concret avec layout contrôlé

```tsx
const CarteComparaison = ({ children, variant = 'vertical' }) => {
const étiquettes = // ... extraction
const contenu = // ... extraction

// Layout horizontal avec Grid
if (variant === 'horizontal') {
return (
<Grid>
<Column1>{étiquettes}</Column1>
<Column2>{contenu}</Column2>
</Grid>
)
}

// Layout vertical avec Flexbox
return (
<Flex direction="column">
{étiquettes}
{contenu}
</Flex>
)
}
```

On garde le contrôle total sur le layout tout en laissant l'utilisateur composer le contenu librement. C'est le meilleur des deux mondes.
19 changes: 19 additions & 0 deletions modele-social/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

## next

## 9.0.0

### Breaking changes
- Renomme la règle `entreprise . imposition . IS . capital détenu au moins à 75 pourcents par des personnes physiques` en `entreprise . capital social . détenu au moins à 75 pourcents par des personnes physiques`

### Nouveautés
- Ajoute la règle `entreprise . imposition . IS . total` qui inclue la contribution
sociale sur l'IS
- Ajoute les règles `salarié . contrat . apprentissage . assiette réduite apprentissage . taxe sur les salaires` et `salarié . contrat . apprentissage . exonération taxe sur les salaires`

### Mises à jour
- Change `entreprise . exercice . date trop ancienne` de 2018 à 2022
- Reformulation de la question de `entreprise . date de cessation`

### Corrections
- Corrige le calcul de `entreprise . exercice . durée`
- Corrige le taux de cotisation maladie sur les revenus non conventionnés pour les médecins conventionnés secteur 2
- Corrige la règle `salarié . contrat . apprentissage . assiette réduite apprentissage . CSG-CRDS` qui ne s'appliquait pas correctement

## 8.0.0

### Breaking changes
Expand Down
2 changes: 1 addition & 1 deletion modele-social/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "modele-social",
"version": "8.0.0",
"version": "9.0.0",
"description": "Les règles publicodes du système social français",
"type": "module",
"main": "./dist/index.js",
Expand Down
9 changes: 3 additions & 6 deletions modele-social/règles/artiste-auteur.publicodes
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,9 @@ artiste-auteur . cotisations . IRCEC . profession:
l’IRCEC : dans tous les cas et si vous atteignez le seuil
d’affiliation, au RAAP, puis selon votre activité artistique au RACD
et/ou au RACL.
formule:
une possibilité:
choix obligatoire: non
possibilités:
- RACD
- RACL
une possibilité:
- RACD
- RACL
par défaut: "''"

artiste-auteur . cotisations . IRCEC . profession . RACD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ déclaration revenus PAMC:
déclaration revenus PAMC . profession:
question: Quelle est votre profession ?
une possibilité:
choix obligatoire: oui
possibilités:
- dentiste
- infirmier
- kinésithérapeute
- médecin secteur 1 généraliste
- médecin secteur 1 spécialiste
- médecin secteur 2
- orthophoniste
- orthoptiste
- pédicure podologue
- sage-femme
- dentiste
- infirmier
- kinésithérapeute
- médecin secteur 1 généraliste
- médecin secteur 1 spécialiste
- médecin secteur 2
- orthophoniste
- orthoptiste
- pédicure podologue
- sage-femme
meta:
requis: oui
avec:
Expand Down Expand Up @@ -70,10 +68,8 @@ déclaration revenus PAMC . statut:
remplaçant/remplaçante et que vous vous êtes installé/installée au 1er juillet,
sélectionnez « Remplaçant / remplaçante ».
une possibilité:
choix obligatoire: oui
possibilités:
- titulaire
- remplaçant
- titulaire
- remplaçant
meta:
requis: oui
avec:
Expand All @@ -86,11 +82,9 @@ déclaration revenus PAMC . statut:
déclaration revenus PAMC . régime fiscal:
question: Quel est votre régime fiscal ?
une possibilité:
choix obligatoire: oui
possibilités:
- IR micro-fiscal
- IR non micro-fiscal
- IS
- IR micro-fiscal
- IR non micro-fiscal
- IS
meta:
requis: oui

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ déclaration charge sociales . comptabilité:
non applicable si: entreprise . imposition . IS
question: Quelle méthode de gestion de la comptabilité est utilisée pour l'entreprise ?
une possibilité:
choix obligatoire: oui
possibilités:
- engagement
- trésorerie
- engagement
- trésorerie

déclaration charge sociales . comptabilité . trésorerie:
# rend non applicable: entreprise . imposition . régime . micro-entreprise
Expand Down Expand Up @@ -68,13 +66,10 @@ déclaration charge sociales . nature de l'activité:
- entreprise . activité . nature
question: Quelle est la nature de votre activité ?
par défaut: "'artisanale'"
valeur:
une possibilité:
choix obligatoire: oui
possibilités:
- artisanale
- commerciale
- libérale
une possibilité:
- artisanale
- commerciale
- libérale
références:
Vérifier la nature de son activité: https://bpifrance-creation.fr/encyclopedie/trouver-proteger-tester-son-idee/verifiertester-son-idee/verifier-nature-son-activite
Comment déterminer la nature de l'activité d'une entreprise ?: https://www.service-public.fr/professionnels-entreprises/vosdroits/F32887
Expand Down
17 changes: 6 additions & 11 deletions modele-social/règles/dirigeant/conjoint-collaborateur.publicodes
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ dirigeant . indépendant . conjoint collaborateur . assiette:
par défaut: "'forfaitaire'"

une possibilité:
choix obligatoire: oui
possibilités:
- forfaitaire
- revenu sans partage
- revenu avec partage
- forfaitaire
- revenu sans partage
- revenu avec partage

avec:
forfaitaire:
Expand All @@ -52,12 +50,9 @@ dirigeant . indépendant . conjoint collaborateur . assiette:
titre: Proportion revenu
question: À quelle proportion du revenu le conjoint cotise-t-il ?
par défaut: "'tiers'"
formule:
une possibilité:
choix obligatoire: oui
possibilités:
- tiers
- moitié
une possibilité:
- tiers
- moitié

avec:
moitié:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ dirigeant . indépendant . cotisations et contributions . déduction tabac . rev
dirigeant . indépendant . cotisations et contributions . début activité:
titre: Cotisations forfaitaires de début d’activité
description: |
Lorsque vous commencez votre activité, vos **revenus professionnels**
n’étant pas connus, **les cotisations et contributions des deux premières
années sont calculées sur une **base forfaitaire**.
Lorsque vous commencez votre activité, vos revenus professionnels n’étant pas
connus, les **cotisations et contributions** des deux premières années sont
calculées sur une **base forfaitaire**.


Ces cotisations seront ajustées et régularisées en fonction de vos revenus réels
Expand Down
Loading