Application pour gérer son équipe de derby.
Le bifrost est l'application qui gère les email et les tâches CRON. les projet est disponible sur Github.
Pour lancer le projet en mode développement:
npm run dev
# or
yarn devOuvrez http://localhost:3000 sur votre navigateur.
La couche entre la fonction et son appel vonlontairement minimal.
Il aurait d'en faire une API GRAPHQL mais le projet doit rester abordable.
Le projet doit pouvoir être déployé par les membres d'une association les plus simplement possible en réduisant les coûts aux maximum.
Il doit être privilégié l'écriture "standalone" d'une nouvelle fonctionnalité.
Le choix d'une base non relationnelle garanti une flexibilité de developpement de nouvelle fonctionnalités.
Le projet initial était en SQL, mais cela demandait d'avoir une vision long terme sur l'ensemble des fonctionnalités. Dans les faits, c'était à peut près le cas, mais le temps disponible pour les réalisé l'était beaucoup moins.
La base peut-être déployé sur Mongo Atlas avec la version gratuite. (vous pouvez choisir votre propre fournisseur, ou auto-hébergé)
Seul les références à d'autre collection peuvent être utilisées. Il doit y avoir dans les documents intégrant un sous document provenant d'une autre collection, suffisament d'information pour retrouver le document référence mais aussi toutes les informations utile permettant l'affichage de valeur.
Il faut prendre en compte qu'il doit y avoir coté fonctionnel la vérification des documents références pouur gérer leurs suppression, modification ...
Exemple:
"user" {
"name":"jane",
"team": [{
"id":"teamd_id",
"name":"ma super team"
}]
}
"teams" {
"id":"teamd_id",
"name":"ma super team",
"description":"Un autre champ non importé"
}
Solution solide et largement répandu et permettant d'intégrer plus facilement de nouveaux développeurs.
Le backend est composé de plusieurs serveless function. Parfois certaines paraissent redondante (modification d'un seul champs...) mais cela permet plusieurs choses :
- moins de compléxité
- gestion des contraintes plus facile à lire
- temps d'execution plus rapide (indispensable sur déployé sur des solutions serverless)
- proximité avec le composant appelant.
Comme les composants frontend, la disparition d'une fonction ne doit pas mettre en peril les autres.
Les vues et la logique sont séparées pour optimiser les tests.
Ils sont rassemblées dans un composant container.
Bien que plus verbeux, chaque fichiers constituant le composant est bien plus léger et garanti d'avoir une responsabilité = un composant.
Component
| component.tsx (container)
| component.view.tsx (vue)
| component.hook.tsx (logique)
| component.module.css (style scopé au composant)
| component.spec.tsx (tests unitaire)
Les composants hook, view et context peuvent être ajouter au même fichier
il est conseillé d'écrire d'abord le composant vue testable directement dans Storybook par exemple. Vous définissez vos interfaces, ce qui sera plus simple pour l'écriture de la logique.
Vous pouvez faire le container pour importer les deux autres, il sera alors plus facile de gérer les props à passer.
Les ref obtenu avec useRef peuvent être intégré directement à la vue.
les composants ayant des props definissent chacun leurs interfaces nommé props;
fonction dans le nom indique l'utilité du composant.
container : refModelFonction
vues: RefModelFonctionView
logique: useRefModelFonction
Le composant ci dessous tranforme une chaîne de caractère en tableau;
Container
interface props {
readonly fruitsCSV:string
}
export default function FruitsList({fruitsCSV}:props){
const props = userFruitsList(fruitsCSV);
return <FruitsListView {...props} />
}Vue
interface props {
readonly fruits:Array<string>
}
export default function FruitsList({fruits}:props){
return <div className={classes.container}/>
{fruits.map((fruit)=> (
<div key={fruit} className={classes.fruit}>{fruit}</div>
)}
</div>
}Logique
Il s'agit d'un hook.
export default function useFruitsList(fruitsCSV:string){
const fruits = useMemo(()=>{
return fruitsCSV.split(',');
}, [fruitsCSV])
return {fruits}
}Il n'y a pas de préprocesseur CSS dans l'application. Le style est géré avec des feuilles de styles globales (définitions des variables...).
Chaque composant peux avoir son style scopé via les modules CSS.
La première classe d'une vue est généralement .container.
Il n'y a jamais plus d'une classe dans une className.
Si vous souhaitez ajouter des dérivés à vos classes ou changer leur état, utilisez les attributs.
La lecture est plus claire dans la vue.
Ici, open est un boolean.
<div className={classes.container} data-open={open}/>
<div className={classes.bar}/>
<div className={classes.bar}/>
<div className={classes.bar}/>
</div>.container {
background: red;
}
.container[data-open="true"] {
background: black;
}
.bar {
display: none;
}
.container[data-open="true"] .bar {
display: block;
}