Skip to content

Commit

Permalink
🔥 😱 on importait les règles yaml de mon-entreprise.fr
Browse files Browse the repository at this point in the history
Et les traductions. Plus de 100kb inutiles et ralentissant le processeur
  • Loading branch information
laem committed Apr 25, 2020
1 parent 16bef12 commit 2536674
Showing 1 changed file with 21 additions and 35 deletions.
56 changes: 21 additions & 35 deletions source/engine/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ import {
take,
toPairs,
trim,
when
when,
} from 'ramda'
import rawRules from 'Règles/base.yaml'
import translations from 'Règles/externalized.yaml'
// TODO - should be in UI, not engine
import { capitalise0, coerceArray } from '../utils'
import { syntaxError, warning } from './error'
Expand All @@ -35,7 +33,7 @@ import possibleVariableTypes from './possibleVariableTypes.yaml'
/***********************************
Functions working on one rule */

export let enrichRule = rule => {
export let enrichRule = (rule) => {
try {
const dottedName = rule.dottedName || rule.nom
const name = nameLeaf(dottedName)
Expand All @@ -55,14 +53,14 @@ export let enrichRule = rule => {
...rule,
dottedName,
name,
type: possibleVariableTypes.find(t => has(t, rule) || rule.type === t),
type: possibleVariableTypes.find((t) => has(t, rule) || rule.type === t),
title: capitalise0(rule['titre'] || name),
defaultValue: rule['par défaut'],
examples: rule['exemples'],
icons: rule['icônes'],
summary: rule['résumé'],
unit,
defaultUnit
defaultUnit,
}
} catch (e) {
syntaxError(
Expand All @@ -82,33 +80,33 @@ export let disambiguateExampleSituation = (rules, rule) =>
fromPairs
)

export let hasKnownRuleType = rule => rule && enrichRule(rule).type
export let hasKnownRuleType = (rule) => rule && enrichRule(rule).type

export let splitName = split(' . '),
joinName = join(' . ')

export let parentName = pipe(splitName, dropLast(1), joinName)
export let nameLeaf = pipe(splitName, last)

export let encodeRuleName = name =>
export let encodeRuleName = (name) =>
encodeURI(
name
.replace(/\s\.\s/g, '/')
.replace(/-/g, '\u2011') // replace with a insecable tiret to differenciate from space
.replace(/\s/g, '-')
)
export let decodeRuleName = name =>
export let decodeRuleName = (name) =>
decodeURI(
name
.replace(/\//g, ' . ')
.replace(/-/g, ' ')
.replace(/\u2011/g, '-')
)

export let ruleParents = dottedName => {
export let ruleParents = (dottedName) => {
let fragments = splitName(dottedName) // dottedName ex. [CDD . événements . rupture]
return range(1, fragments.length)
.map(nbEl => take(nbEl)(fragments))
.map((nbEl) => take(nbEl)(fragments))
.reverse() // -> [ [CDD . événements . rupture], [CDD . événements], [CDD] ]
}
/* In a formula, variables can be cited without referring to them absolutely : namespaces can be omitted to enhance the readability. This function resolves this ambiguity.
Expand All @@ -121,7 +119,7 @@ export let disambiguateRuleReference = (
let pathPossibilities = [
splitName(dottedName), // the rule's own namespace
...ruleParents(dottedName), // the parent namespaces
[] // the top level namespace
[], // the top level namespace
],
found = reduce(
(res, path) => {
Expand Down Expand Up @@ -165,7 +163,7 @@ export let findRulesByName = (allRules, query) =>

export let findRuleByDottedName = (allRules, dottedName) =>
Array.isArray(allRules)
? allRules.find(rule => rule.dottedName == dottedName)
? allRules.find((rule) => rule.dottedName == dottedName)
: allRules[dottedName]

export let findRule = (rules, nameOrDottedName) =>
Expand All @@ -174,14 +172,14 @@ export let findRule = (rules, nameOrDottedName) =>
: findRuleByName(rules, nameOrDottedName)

export let findRuleByNamespace = (allRules, ns) =>
allRules.filter(rule => parentName(rule.dottedName) === ns)
allRules.filter((rule) => parentName(rule.dottedName) === ns)

/*********************************
Autres */

export let queryRule = rule => query => path(query.split(' . '))(rule)
export let queryRule = (rule) => (query) => path(query.split(' . '))(rule)

export let nestedSituationToPathMap = situation => {
export let nestedSituationToPathMap = (situation) => {
if (situation == undefined) return {}
let rec = (o, currentPath) =>
typeof o === 'object'
Expand All @@ -194,7 +192,7 @@ export let nestedSituationToPathMap = situation => {
/* Traduction */

export let translateAll = (translations, flatRules) => {
let translationsOf = rule => translations[rule.dottedName],
let translationsOf = (rule) => translations[rule.dottedName],
translateProp = (lang, translation) => (rule, prop) => {
let propTrans = translation[prop + '.' + lang]
if (prop === 'suggestions' && propTrans)
Expand All @@ -204,15 +202,15 @@ export let translateAll = (translations, flatRules) => {
toPairs,
map(([key, translatedKey]) => [
translatedKey,
rule.suggestions[key]
rule.suggestions[key],
]),
fromPairs
)(propTrans),
rule
)
return propTrans ? assoc(prop, propTrans, rule) : rule
},
translateRule = (lang, translations, props) => rule => {
translateRule = (lang, translations, props) => (rule) => {
let ruleTrans = translationsOf(rule)
return ruleTrans
? reduce(translateProp(lang, ruleTrans), rule, props)
Expand All @@ -225,31 +223,19 @@ export let translateAll = (translations, flatRules) => {
'question',
'résumé',
'suggestions',
'contrôles'
'contrôles',
]

return map(translateRule('en', translations, targets), flatRules)
}

const rulesList = Object.entries(rawRules).map(([dottedName, rule]) => ({
dottedName,
...rule
}))

// On enrichit la base de règles avec des propriétés dérivées de celles du YAML
export let rules = translateAll(translations, rulesList).map(rule =>
enrichRule(rule)
)

export let rulesFr = rulesList.map(rule => enrichRule(rule))

export let findParentDependencies = (rules, rule) => {
// A parent dependency means that one of a rule's parents is not just a namespace holder, it is a boolean question. E.g. is it a fixed-term contract, yes / no
// When it is resolved to false, then the whole branch under it is disactivated (non applicable)
// It lets those children omit obvious and repetitive parent applicability tests
let parentDependencies = ruleParents(rule.dottedName).map(joinName)
return pipe(
map(parent => findRuleByDottedName(rules, parent)),
map((parent) => findRuleByDottedName(rules, parent)),
reject(isNil),
filter(
//Find the first "calculable" parent
Expand All @@ -263,14 +249,14 @@ export let findParentDependencies = (rules, rule) => {
)(parentDependencies)
}

export let getRuleFromAnalysis = analysis => dottedName => {
export let getRuleFromAnalysis = (analysis) => (dottedName) => {
if (!analysis) {
throw new Error("[getRuleFromAnalysis] The analysis can't be nil !")
}

let rule = coerceArray(analysis) // In some simulations, there are multiple "branches" : the analysis is run with e.g. 3 different input situations
.map(
analysis =>
(analysis) =>
analysis.cache[dottedName]?.explanation || // the cache stores a reference to a variable, the variable is contained in the 'explanation' attribute
analysis.targets.find(propEq('dottedName', dottedName))
)
Expand Down

0 comments on commit 2536674

Please sign in to comment.