[{"data":1,"prerenderedAt":658},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fbring-your-schema":189},[4],{"title":5,"path":6,"stem":7,"children":8,"page":52},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,31,53,78,123,148],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"Une app que vous avez déjà","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"Apportez votre schéma","\u002Ffr\u002Fdocs\u002Fbring-your-schema","fr\u002Fdocs\u002F03.bring-your-schema",{"title":28,"path":29,"stem":30},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F04.cli",{"title":32,"path":33,"stem":34,"children":35,"page":52},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[36,40,44,48],{"title":37,"path":38,"stem":39},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":41,"path":42,"stem":43},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":45,"path":46,"stem":47},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",{"title":49,"path":50,"stem":51},"Le socle","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fthe-base","fr\u002Fdocs\u002F2.concepts\u002F4.the-base",false,{"title":54,"path":55,"stem":56,"children":57,"page":52},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":63,"path":64,"stem":65},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":67,"path":68,"stem":69},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":71,"path":72,"stem":73},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":75,"path":76,"stem":77},"Comment un schéma bouge","\u002Ffr\u002Fdocs\u002Fschema\u002Fevolution","fr\u002Fdocs\u002F3.schema\u002F5.evolution",{"title":79,"path":80,"stem":81,"children":82,"page":52},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":88,"path":89,"stem":90},"Les ports","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fports","fr\u002Fdocs\u002F4.business\u002F10.ports",{"title":92,"path":93,"stem":94},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":96,"path":97,"stem":98},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":100,"path":101,"stem":102},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":104,"path":105,"stem":106},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":108,"path":109,"stem":110},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":112,"path":113,"stem":114},"Le port Storage","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage","fr\u002Fdocs\u002F4.business\u002F7.storage",{"title":116,"path":117,"stem":118},"Des écritures qui tiennent ou tombent ensemble","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether","fr\u002Fdocs\u002F4.business\u002F8.together",{"title":120,"path":121,"stem":122},"Les repositories","\u002Ffr\u002Fdocs\u002Fbusiness\u002Frepositories","fr\u002Fdocs\u002F4.business\u002F9.repositories",{"title":124,"path":125,"stem":126,"children":127,"page":52},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[128,132,136,140,144],{"title":129,"path":130,"stem":131},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":133,"path":134,"stem":135},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":137,"path":138,"stem":139},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":141,"path":142,"stem":143},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":145,"path":146,"stem":147},"Back-office","\u002Ffr\u002Fdocs\u002Fclient\u002Fadmin","fr\u002Fdocs\u002F5.client\u002F5.admin",{"title":149,"path":150,"stem":151,"children":152,"page":52},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[153,157,161,165,169,173,177,181,185],{"title":154,"path":155,"stem":156},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":158,"path":159,"stem":160},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":162,"path":163,"stem":164},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":166,"path":167,"stem":168},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"title":170,"path":171,"stem":172},"Les sources","\u002Ffr\u002Fdocs\u002Finfra\u002Fsources","fr\u002Fdocs\u002F6.infra\u002F5.sources",{"title":174,"path":175,"stem":176},"Le cycle de vie","\u002Ffr\u002Fdocs\u002Finfra\u002Flifecycle","fr\u002Fdocs\u002F6.infra\u002F6.lifecycle",{"title":178,"path":179,"stem":180},"L'identité entre Fronds","\u002Ffr\u002Fdocs\u002Finfra\u002Fidentity","fr\u002Fdocs\u002F6.infra\u002F7.identity",{"title":182,"path":183,"stem":184},"Observabilité","\u002Ffr\u002Fdocs\u002Finfra\u002Fobservability","fr\u002Fdocs\u002F6.infra\u002F8.observability",{"title":186,"path":187,"stem":188},"Tests","\u002Ffr\u002Fdocs\u002Finfra\u002Ftesting","fr\u002Fdocs\u002F6.infra\u002F9.testing",{"id":190,"title":24,"body":191,"description":652,"extension":653,"meta":654,"navigation":655,"path":25,"seo":656,"stem":26,"__hash__":657},"docs_fr\u002Ffr\u002Fdocs\u002F03.bring-your-schema.md",{"type":192,"value":193,"toc":644},"minimark",[194,198,211,218,223,226,248,258,262,492,509,513,520,579,590,596,603,607,638],[195,196,24],"h1",{"id":197},"apportez-votre-schéma",[199,200,201,202,206,207,210],"p",{},"La page précédente est additive sur l'",[203,204,205],"strong",{},"hôte"," : votre routing, vos pages, votre rendu et\nvos autres routes serveur ne bougent pas. Elle ne l'est pas sur le ",[203,208,209],{},"domaine",". L'entité est\nla seule chose que Fougere doit posséder, parce que c'est la seule dont tout le reste dérive.",[199,212,213,214,217],{},"Adopter Fougere a donc exactement un coût, et cette page est ce coût : ",[203,215,216],{},"vous déclarez votre\nmodèle dans son vocabulaire",". La suite explique comment le garder petit, borné, et payé une\nentité à la fois.",[219,220,222],"h2",{"id":221},"une-entité-à-la-fois","Une entité à la fois",[199,224,225],{},"On ne convertit pas un domaine. On convertit une entité.",[199,227,228,232,233,236,237,236,240,243,244,247],{},[229,230,231],"code",{},"migrate()"," est additif : il émet ",[229,234,235],{},"createTable",", ",[229,238,239],{},"addColumn",[229,241,242],{},"addConstraint"," et\n",[229,245,246],{},"createIndex",", rien d'autre. Il ne supprime jamais une colonne, ne réécrit jamais un type,\net ne propose rien pour une table qu'aucune entité ne déclare. Une entité Fougere crée donc\nsa table à côté de celles que gère votre storage actuel, dans la même base, et vos lignes\nexistantes sont hors de sa portée.",[199,249,250,251,253,254,257],{},"Le cas à surveiller est la collision de noms : pour une entité dont la table existe déjà,\nc'est un ",[229,252,239],{}," ",[203,255,256],{},"sur votre table"," qui est proposé, pas une table neuve. Renommez\nl'une des deux, ou confiez la table volontairement.",[219,259,261],{"id":260},"la-correspondance","La correspondance",[263,264,265,278],"table",{},[266,267,268],"thead",{},[269,270,271,275],"tr",{},[272,273,274],"th",{},"Prisma",[272,276,277],{},"Fougere",[279,280,281,299,316,331,343,355,367,379,391,407,419,432,443,455,467,480],"tbody",{},[269,282,283,289],{},[284,285,286],"td",{},[229,287,288],{},"String",[284,290,291,294,295,298],{},[229,292,293],{},"text()"," — avec ",[229,296,297],{},"{ min, max }"," quand vous avez une règle",[269,300,301,306],{},[284,302,303],{},[229,304,305],{},"String?",[284,307,308,311,312,315],{},[229,309,310],{},"optional(text())",", ou ",[229,313,314],{},"nullable(text())"," si la colonne est vraiment nullable",[269,317,318,326],{},[284,319,320,236,323],{},[229,321,322],{},"Int",[229,324,325],{},"Float",[284,327,328],{},[229,329,330],{},"number()",[269,332,333,338],{},[284,334,335],{},[229,336,337],{},"Boolean",[284,339,340],{},[229,341,342],{},"bool()",[269,344,345,350],{},[284,346,347],{},[229,348,349],{},"DateTime",[284,351,352],{},[229,353,354],{},"date()",[269,356,357,362],{},[284,358,359],{},[229,360,361],{},"Json",[284,363,364],{},[229,365,366],{},"json()",[269,368,369,374],{},[284,370,371],{},[229,372,373],{},"String @id @default(cuid())",[284,375,376],{},[229,377,378],{},"primary()",[269,380,381,386],{},[284,382,383],{},[229,384,385],{},"@unique",[284,387,388],{},[229,389,390],{},"unique(champ)",[269,392,393,398],{},[284,394,395],{},[229,396,397],{},"@@unique([listId, docId])",[284,399,400,403,404],{},[229,401,402],{},"unique: [['listId', 'docId']]",", dans le 2ᵉ argument d'",[229,405,406],{},"entity()",[269,408,409,414],{},[284,410,411],{},[229,412,413],{},"@index",[284,415,416],{},[229,417,418],{},"indexed(champ)",[269,420,421,427],{},[284,422,423,424],{},"une clé étrangère + ",[229,425,426],{},"@relation",[284,428,429],{},[229,430,431],{},"ref(Author)",[269,433,434,437],{},[284,435,436],{},"l'autre côté de cette relation",[284,438,439,442],{},[229,440,441],{},"many(Post)"," — un rôle, pas de colonne",[269,444,445,450],{},[284,446,447],{},[229,448,449],{},"@default(now())",[284,451,452],{},[229,453,454],{},"created()",[269,456,457,462],{},[284,458,459],{},[229,460,461],{},"@updatedAt",[284,463,464],{},[229,465,466],{},"updated()",[269,468,469,475],{},[284,470,471,472],{},"une enum + ",[229,473,474],{},"@default(\"draft\")",[284,476,477],{},[229,478,479],{},"oneOf('draft', 'published', { default: 'draft' })",[269,481,482,487],{},[284,483,484],{},[229,485,486],{},"@db.VarChar(160)",[284,488,489],{},[229,490,491],{},"text({ max: 160 })",[199,493,494,495,497,498,500,501,504,505,508],{},"La dernière ligne, c'est toute la thèse. ",[229,496,486],{}," nomme un dialecte ;\n",[229,499,491],{}," nomme la règle, et le dialecte en dérive — avec le ",[229,502,503],{},"CHECK",", le JSON\nSchema, le type GraphQL et le ",[229,506,507],{},"maxlength"," du formulaire.",[219,510,512],{"id":511},"ce-qui-na-pas-déquivalent","Ce qui n'a pas d'équivalent",[199,514,515,516,519],{},"Un modèle Prisma dit ce que la colonne ",[203,517,518],{},"est",". C'est un axe sur quatre. Les trois autres\nn'ont aucune colonne d'où partir, et c'est pour ça que la conversion n'est pas mécanique :",[521,522,523,542,558],"ul",{},[524,525,526,253,532,534,535,537,538,541],"li",{},[203,527,528,531],{},[229,529,530],{},"lifecycle"," — qui écrit la valeur, et quand.",[229,533,454],{}," n'est pas ",[229,536,449],{},"\nsous un plus joli nom : il énonce aussi que la valeur ne peut pas être réécrite à\nl'update. ",[229,539,540],{},"readOnly(oneOf(…))"," énonce que le client ne la fournit jamais.",[524,543,544,253,550,553,554,557],{},[203,545,546,549],{},[229,547,548],{},"boundary"," — qui a le droit de la voir.",[229,551,552],{},"writeOnly()"," pour le mot de passe qui entre\net ne ressort pas. ",[229,555,556],{},"readOnly()"," pour le champ que le serveur estampille.",[524,559,560,253,566,236,569,236,572,236,575,578],{},[203,561,562,565],{},[229,563,564],{},"role"," — quel rôle il joue.",[229,567,568],{},"primary",[229,570,571],{},"ref",[229,573,574],{},"many",[229,576,577],{},"unique"," — lus par le DDL pour\nles clés et les contraintes, et par la carte pour les relations.",[199,580,581,582,585,586,589],{},"Ces trois règles, vous les appliquez déjà. Elles vivent dans une méthode de service, un DTO,\nune clause ",[229,583,584],{},"select:",", un décorateur ",[229,587,588],{},"@Exclude()",", un commentaire de revue. Ce sont de vraies\nrègles sans domicile unique.",[591,592,593],"blockquote",{},[199,594,595],{},"La conversion n'est pas mécanique parce que vous écrivez, pour la première fois, des\nrègles que vous appliquiez déjà.",[199,597,598,599,602],{},"C'est le travail, et c'est aussi le retour : de cette déclaration, le validateur, la table,\nle type GraphQL, la route REST et le contrat de formulaire sont tous des projections — voir\n",[600,601,59],"a",{"href":60}," pour les quatre axes en entier.",[219,604,606],{"id":605},"ce-qui-ne-bouge-pas","Ce qui ne bouge pas",[521,608,609,615,625],{},[524,610,611,614],{},[203,612,613],{},"Votre storage."," Fougere ne le revendique pas. Dans les routes que vous n'avez pas\nconverties, continuez d'interroger exactement comme aujourd'hui.",[524,616,617,620,621,624],{},[203,618,619],{},"Les tables non converties."," Rien au boot n'exige que toute la base soit déclarée. Le\nscan trouve ce qui est dans ",[229,622,623],{},"entities\u002F",", et se tait sur le reste.",[524,626,627,253,630,633,634,637],{},[203,628,629],{},"Les requêtes brutes sur une entité convertie.",[229,631,632],{},"storage.client"," est le passe-droit du port\nstorage — l'instance Kysely sous-jacente pour l'adapter SQL, cantonnée aux données de cette\nentité. C'est le seul chemin sur lequel le juge ne siège pas ; voir\n",[600,635,112],{"href":636},"\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage#client--et-ce-quil-co%C3%BBte",".",[199,639,640,641,643],{},"Suite : ",[600,642,28],{"href":29}," — composer un workspace, héberger une Frond, appeler une opération.",{"title":645,"searchDepth":646,"depth":646,"links":647},"",2,[648,649,650,651],{"id":221,"depth":646,"text":222},{"id":260,"depth":646,"text":261},{"id":511,"depth":646,"text":512},{"id":605,"depth":646,"text":606},"Ce que devient un modèle Prisma ou Drizzle — et la part que vous écrivez pour la première fois.","md",{},true,{"title":24,"description":652},"N3GB6lMcV4jm1dRfMMd9j0pEG4lYob5oHbLrLeb9qPI",1788598418927]