[{"data":1,"prerenderedAt":1510},["ShallowReactive",2],{"fougere:post.list:{}":3,"docs:\u002Fdocs\u002Fserve\u002Fadmin":6,"docs-uses":1202,"docs-nav":1372},{"items":4,"hasMore":5},[],false,{"id":7,"title":8,"body":9,"description":1190,"extension":1191,"forms":1192,"kind":1193,"meta":1194,"navigation":160,"path":1195,"seo":1196,"stem":1197,"step":1198,"uses":1199,"__hash__":1201},"docs\u002Fdocs\u002F5.serve\u002F4.admin.md","An admin panel",{"type":10,"value":11,"toc":1181},"minimark",[12,25,108,188,195,200,381,395,399,402,449,456,460,472,655,666,670,673,805,823,936,940,954,1082,1086,1093,1101,1107,1119,1123,1177],[13,14,15,16,20,21,24],"p",{},"A back-office asks four questions: which subjects exist, what a row shows, what a form takes, and\nwhich actions are allowed. The app's identity card — what ",[17,18,19],"code",{},"rpc.discover"," answers — already says all\nfour, so ",[17,22,23],{},"@fougere\u002Fadmin"," generates nothing and declares nothing: it reads the card when it loads and\nrenders it.",[26,27,31,59,76,92],"code-group",{"className":28,"sync":30},[29],"managers","pm",[32,33,39],"pre",{"className":34,"code":35,"filename":36,"language":37,"meta":38,"style":38},"language-bash shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","npm install @fougere\u002Fadmin react-admin\n","npm","bash","",[17,40,41],{"__ignoreMap":38},[42,43,46,49,53,56],"span",{"class":44,"line":45},"line",1,[42,47,36],{"class":48},"sV8pK",[42,50,52],{"class":51},"sN-8n"," install",[42,54,55],{"class":51}," @fougere\u002Fadmin",[42,57,58],{"class":51}," react-admin\n",[32,60,63],{"className":34,"code":61,"filename":62,"language":37,"meta":38,"style":38},"pnpm add @fougere\u002Fadmin react-admin\n","pnpm",[17,64,65],{"__ignoreMap":38},[42,66,67,69,72,74],{"class":44,"line":45},[42,68,62],{"class":48},[42,70,71],{"class":51}," add",[42,73,55],{"class":51},[42,75,58],{"class":51},[32,77,80],{"className":34,"code":78,"filename":79,"language":37,"meta":38,"style":38},"bun add @fougere\u002Fadmin react-admin\n","bun",[17,81,82],{"__ignoreMap":38},[42,83,84,86,88,90],{"class":44,"line":45},[42,85,79],{"class":48},[42,87,71],{"class":51},[42,89,55],{"class":51},[42,91,58],{"class":51},[32,93,96],{"className":34,"code":94,"filename":95,"language":37,"meta":38,"style":38},"yarn add @fougere\u002Fadmin react-admin\n","yarn",[17,97,98],{"__ignoreMap":38},[42,99,100,102,104,106],{"class":44,"line":45},[42,101,95],{"class":48},[42,103,71],{"class":51},[42,105,55],{"class":51},[42,107,58],{"class":51},[32,109,113],{"className":110,"code":111,"language":112,"meta":38,"style":38},"language-tsx shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","\u002F\u002F app\u002Fadmin.tsx — the whole file\nimport { FougereAdmin } from '@fougere\u002Fadmin\u002Freact';\n\nexport default () => \u003CFougereAdmin \u002F>;\n","tsx",[17,114,115,121,155,162],{"__ignoreMap":38},[42,116,117],{"class":44,"line":45},[42,118,120],{"class":119},"skXKP","\u002F\u002F app\u002Fadmin.tsx — the whole file\n",[42,122,124,128,132,136,139,142,146,149,152],{"class":44,"line":123},2,[42,125,127],{"class":126},"sK6XW","import",[42,129,131],{"class":130},"s15xx"," {",[42,133,135],{"class":134},"sPEhv"," FougereAdmin",[42,137,138],{"class":130}," }",[42,140,141],{"class":126}," from",[42,143,145],{"class":144},"sDDC1"," '",[42,147,148],{"class":51},"@fougere\u002Fadmin\u002Freact",[42,150,151],{"class":144},"'",[42,153,154],{"class":130},";\n",[42,156,158],{"class":44,"line":157},3,[42,159,161],{"emptyLinePlaceholder":160},true,"\n",[42,163,165,168,171,174,178,181,185],{"class":44,"line":164},4,[42,166,167],{"class":126},"export",[42,169,170],{"class":126}," default",[42,172,173],{"class":130}," ()",[42,175,177],{"class":176},"scTuO"," =>",[42,179,180],{"class":130}," \u003C",[42,182,184],{"class":183},"sBZYL","FougereAdmin",[42,186,187],{"class":130}," \u002F>;\n",[13,189,190,191,194],{},"Every entity, with nothing more to write. A new ",[17,192,193],{},"class Invoice extends entity({…})"," appears in the\nmenu at the next load, because the card now lists its facade.",[196,197,199],"h2",{"id":198},"what-each-screen-is-read-from","What each screen is read from",[201,202,203,219],"table",{},[204,205,206],"thead",{},[207,208,209,213,216],"tr",{},[210,211,212],"th",{},"Screen",[210,214,215],{},"Read from",[210,217,218],{},"Function",[220,221,222,240,256,272,298,319,335,352,368],"tbody",{},[207,223,224,228,233],{},[225,226,227],"td",{},"The menu",[225,229,230],{},[17,231,232],{},"card.fronds[].facades[]",[225,234,235,236,239],{},"a facade whose ",[17,237,238],{},"list"," answers no entity is not furniture",[207,241,242,245,251],{},[225,243,244],{},"A list's columns",[225,246,247,250],{},[17,248,249],{},"Visibility.output"," + the shape",[225,252,253],{},[17,254,255],{},"tableColumnsOf",[207,257,258,261,267],{},[225,259,260],{},"A form's inputs",[225,262,263,266],{},[17,264,265],{},"Visibility.input"," + the lifecycle axis",[225,268,269],{},[17,270,271],{},"formFieldsOf",[207,273,274,277,293],{},[225,275,276],{},"Its bounds",[225,278,279,282,283,286,287,286,290],{},[17,280,281],{},"shape"," → ",[17,284,285],{},"minLength",", ",[17,288,289],{},"max",[17,291,292],{},"pattern",[225,294,295],{},[17,296,297],{},"field.attrs",[207,299,300,303,313],{},[225,301,302],{},"A reference",[225,304,305,306,309,310],{},"the ",[17,307,308],{},"relation"," role, then the target's first ",[17,311,312],{},"text()",[225,314,315,318],{},[17,316,317],{},"field.reference",", searched twenty at a time",[207,320,321,324,330],{},[225,322,323],{},"A row's identity",[225,325,305,326,329],{},[17,327,328],{},"primary"," role",[225,331,332],{},[17,333,334],{},"FieldSet.of(fields).primary",[207,336,337,340,345],{},[225,338,339],{},"The buttons",[225,341,342],{},[17,343,344],{},"facade.ops",[225,346,347,348,351],{},"no ",[17,349,350],{},"create"," op, no create button",[207,353,354,357,362],{},[225,355,356],{},"A refusal",[225,358,359],{},[17,360,361],{},"VALIDATION_FAILED",[225,363,364,367],{},[17,365,366],{},"errorsByField",", per field",[207,369,370,373,378],{},[225,371,372],{},"Topology",[225,374,375],{},[17,376,377],{},"rpc.topology",[225,379,380],{},"the one screen the card does not answer",[13,382,383,385,386,388,389,394],{},[17,384,255],{}," reads what may leave, ",[17,387,271],{}," what a client may write — the same pair\n",[390,391,393],"a",{"href":392},"\u002Fdocs\u002Fserve\u002Fforms","a form"," uses. The panel adds no reading of its own.",[196,396,398],{"id":397},"the-gradient-reaches-it","The gradient reaches it",[13,400,401],{},"The panel talks to the call endpoint and knows nothing else, so this line changes nothing for it:",[32,403,407],{"className":404,"code":405,"language":406,"meta":38,"style":38},"language-ts shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","\u002F\u002F fougere.config.ts\nfronds: { billing: { remote: 'https:\u002F\u002Fbilling.internal' } }\n","ts",[17,408,409,414],{"__ignoreMap":38},[42,410,411],{"class":44,"line":45},[42,412,413],{"class":119},"\u002F\u002F fougere.config.ts\n",[42,415,416,420,423,425,428,430,432,435,437,439,442,444,446],{"class":44,"line":123},[42,417,419],{"class":418},"sWI7z","fronds",[42,421,422],{"class":130},":",[42,424,131],{"class":130},[42,426,427],{"class":418}," billing",[42,429,422],{"class":130},[42,431,131],{"class":130},[42,433,434],{"class":418}," remote",[42,436,422],{"class":130},[42,438,145],{"class":144},[42,440,441],{"class":51},"https:\u002F\u002Fbilling.internal",[42,443,151],{"class":144},[42,445,138],{"class":130},[42,447,448],{"class":130}," }\n",[13,450,451,452,455],{},"The ",[17,453,454],{},"invoice"," facade moves to another process, the card still lists it, and the same build renders\nthe same screens.",[196,457,459],{"id":458},"facets-declared-never-guessed","Facets — declared, never guessed",[13,461,462,463,466,467,471],{},"Some things a screen wants are not in the entity. ",[17,464,465],{},"oneOf('draft', 'published')"," says the set is\nclosed; it never says which value means ",[468,469,470],"em",{},"published",". You say it:",[32,473,475],{"className":404,"code":474,"language":406,"meta":38,"style":38},"import { defineAdminExtension } from '@fougere\u002Fadmin';\n\ndefineAdminExtension({\n  resource: 'post',\n  facets: {\n    editorial: {\n      title: 'title',\n      state: { field: 'status', draft: ['draft'], published: ['published'] },\n    },\n  },\n})\n",[17,476,477,498,502,515,533,544,554,571,634,640,646],{"__ignoreMap":38},[42,478,479,481,483,486,488,490,492,494,496],{"class":44,"line":45},[42,480,127],{"class":126},[42,482,131],{"class":130},[42,484,485],{"class":134}," defineAdminExtension",[42,487,138],{"class":130},[42,489,141],{"class":126},[42,491,145],{"class":144},[42,493,23],{"class":51},[42,495,151],{"class":144},[42,497,154],{"class":130},[42,499,500],{"class":44,"line":123},[42,501,161],{"emptyLinePlaceholder":160},[42,503,504,508,512],{"class":44,"line":157},[42,505,507],{"class":506},"s4mR9","defineAdminExtension",[42,509,511],{"class":510},"srlTG","(",[42,513,514],{"class":130},"{\n",[42,516,517,521,523,525,528,530],{"class":44,"line":164},[42,518,520],{"class":519},"sHtqg","  resource",[42,522,422],{"class":130},[42,524,145],{"class":144},[42,526,527],{"class":51},"post",[42,529,151],{"class":144},[42,531,532],{"class":130},",\n",[42,534,536,539,541],{"class":44,"line":535},5,[42,537,538],{"class":519},"  facets",[42,540,422],{"class":130},[42,542,543],{"class":130}," {\n",[42,545,547,550,552],{"class":44,"line":546},6,[42,548,549],{"class":519},"    editorial",[42,551,422],{"class":130},[42,553,543],{"class":130},[42,555,557,560,562,564,567,569],{"class":44,"line":556},7,[42,558,559],{"class":519},"      title",[42,561,422],{"class":130},[42,563,145],{"class":144},[42,565,566],{"class":51},"title",[42,568,151],{"class":144},[42,570,532],{"class":130},[42,572,574,577,579,581,584,586,588,591,593,596,599,601,604,606,609,611,614,616,619,621,623,625,627,629,631],{"class":44,"line":573},8,[42,575,576],{"class":519},"      state",[42,578,422],{"class":130},[42,580,131],{"class":130},[42,582,583],{"class":519}," field",[42,585,422],{"class":130},[42,587,145],{"class":144},[42,589,590],{"class":51},"status",[42,592,151],{"class":144},[42,594,595],{"class":130},",",[42,597,598],{"class":519}," draft",[42,600,422],{"class":130},[42,602,603],{"class":510}," [",[42,605,151],{"class":144},[42,607,608],{"class":51},"draft",[42,610,151],{"class":144},[42,612,613],{"class":510},"]",[42,615,595],{"class":130},[42,617,618],{"class":519}," published",[42,620,422],{"class":130},[42,622,603],{"class":510},[42,624,151],{"class":144},[42,626,470],{"class":51},[42,628,151],{"class":144},[42,630,613],{"class":510},[42,632,633],{"class":130}," },\n",[42,635,637],{"class":44,"line":636},9,[42,638,639],{"class":130},"    },\n",[42,641,643],{"class":44,"line":642},10,[42,644,645],{"class":130},"  },\n",[42,647,649,652],{"class":44,"line":648},11,[42,650,651],{"class":130},"}",[42,653,654],{"class":510},")\n",[13,656,657,658,661,662,665],{},"Nothing is guessed from a field's name: an entity writing ",[17,659,660],{},"titre"," or ",[17,663,664],{},"brouillon"," would lose its facet\nwithout a word. With no facet declared, the table read from the card is still the whole back-office.",[196,667,669],{"id":668},"extensions-are-deltas","Extensions are deltas",[13,671,672],{},"An extension names only what it changes, so a field added to the entity tomorrow still appears:",[32,674,676],{"className":404,"code":675,"language":406,"meta":38,"style":38},"defineAdminExtension({\n  resource: 'post',\n  label: 'Articles',\n  fields: { internalNote: { hidden: true }, title: { label: 'Headline' } },\n  operations: { publish: { confirm: 'Publish this article?' } },\n})\n",[17,677,678,686,700,716,767,799],{"__ignoreMap":38},[42,679,680,682,684],{"class":44,"line":45},[42,681,507],{"class":506},[42,683,511],{"class":510},[42,685,514],{"class":130},[42,687,688,690,692,694,696,698],{"class":44,"line":123},[42,689,520],{"class":519},[42,691,422],{"class":130},[42,693,145],{"class":144},[42,695,527],{"class":51},[42,697,151],{"class":144},[42,699,532],{"class":130},[42,701,702,705,707,709,712,714],{"class":44,"line":157},[42,703,704],{"class":519},"  label",[42,706,422],{"class":130},[42,708,145],{"class":144},[42,710,711],{"class":51},"Articles",[42,713,151],{"class":144},[42,715,532],{"class":130},[42,717,718,721,723,725,728,730,732,735,737,741,744,747,749,751,754,756,758,761,763,765],{"class":44,"line":164},[42,719,720],{"class":519},"  fields",[42,722,422],{"class":130},[42,724,131],{"class":130},[42,726,727],{"class":519}," internalNote",[42,729,422],{"class":130},[42,731,131],{"class":130},[42,733,734],{"class":519}," hidden",[42,736,422],{"class":130},[42,738,740],{"class":739},"slmMI"," true",[42,742,743],{"class":130}," },",[42,745,746],{"class":519}," title",[42,748,422],{"class":130},[42,750,131],{"class":130},[42,752,753],{"class":519}," label",[42,755,422],{"class":130},[42,757,145],{"class":144},[42,759,760],{"class":51},"Headline",[42,762,151],{"class":144},[42,764,138],{"class":130},[42,766,633],{"class":130},[42,768,769,772,774,776,779,781,783,786,788,790,793,795,797],{"class":44,"line":535},[42,770,771],{"class":519},"  operations",[42,773,422],{"class":130},[42,775,131],{"class":130},[42,777,778],{"class":519}," publish",[42,780,422],{"class":130},[42,782,131],{"class":130},[42,784,785],{"class":519}," confirm",[42,787,422],{"class":130},[42,789,145],{"class":144},[42,791,792],{"class":51},"Publish this article?",[42,794,151],{"class":144},[42,796,138],{"class":130},[42,798,633],{"class":130},[42,800,801,803],{"class":44,"line":546},[42,802,651],{"class":130},[42,804,654],{"class":510},[13,806,807,808,286,811,286,814,286,817,286,820,422],{},"For anything finer, one renderer replaces one field, and every React Admin prop still\nworks — ",[17,809,810],{},"theme",[17,812,813],{},"layout",[17,815,816],{},"authProvider",[17,818,819],{},"i18nProvider",[17,821,822],{},"dashboard",[32,824,826],{"className":110,"code":825,"language":112,"meta":38,"style":38},"\u003CFougereAdmin\n  renderers={{ fields: { 'user.role': ({ column }) => \u003CChipField source={column.name} \u002F> } }}\n  resourceComponents={{ post: { list: MyPostList } }}\n\u002F>\n",[17,827,828,836,905,931],{"__ignoreMap":38},[42,829,830,833],{"class":44,"line":45},[42,831,832],{"class":130},"\u003C",[42,834,835],{"class":183},"FougereAdmin\n",[42,837,838,842,845,848,850,852,854,858,860,862,865,869,872,874,876,879,882,885,888,891,895,897,900,902],{"class":44,"line":123},[42,839,841],{"class":840},"s8ClO","  renderers",[42,843,844],{"class":130},"={{",[42,846,847],{"class":519}," fields",[42,849,422],{"class":130},[42,851,131],{"class":130},[42,853,145],{"class":144},[42,855,857],{"class":856},"sK7Y8","user.role",[42,859,151],{"class":144},[42,861,422],{"class":130},[42,863,864],{"class":130}," ({",[42,866,868],{"class":867},"shDUQ"," column",[42,870,871],{"class":130}," })",[42,873,177],{"class":176},[42,875,180],{"class":130},[42,877,878],{"class":183},"ChipField",[42,880,881],{"class":840}," source",[42,883,884],{"class":130},"={",[42,886,887],{"class":134},"column",[42,889,890],{"class":130},".",[42,892,894],{"class":893},"sy9f4","name",[42,896,651],{"class":130},[42,898,899],{"class":130}," \u002F>",[42,901,138],{"class":130},[42,903,904],{"class":130}," }}\n",[42,906,907,910,912,915,917,919,922,924,927,929],{"class":44,"line":157},[42,908,909],{"class":840},"  resourceComponents",[42,911,844],{"class":130},[42,913,914],{"class":519}," post",[42,916,422],{"class":130},[42,918,131],{"class":130},[42,920,921],{"class":519}," list",[42,923,422],{"class":130},[42,925,926],{"class":134}," MyPostList ",[42,928,651],{"class":130},[42,930,904],{"class":130},[42,932,933],{"class":44,"line":164},[42,934,935],{"class":130},"\u002F>\n",[196,937,939],{"id":938},"it-speaks-no-language","It speaks no language",[13,941,942,943,946,947,950,951,953],{},"Every visible sentence goes through a key: ",[17,944,945],{},"fougere.admin.*"," for the panel's own widgets,\n",[17,948,949],{},"entity.field"," for a field, with the field's name when no key answers. An untranslated admin is\nEnglish, and an ",[17,952,819],{}," filling those keys is the whole translation.",[32,955,957],{"className":404,"code":956,"language":406,"meta":38,"style":38},"polyglotI18nProvider(() => ({\n  ...frenchMessages,\n  fougere: { admin: { overview: { title: \"Vue d'ensemble\" } } },\n  post: { title: 'Titre', status: 'Statut' },\n}), 'fr')\n",[17,958,959,976,986,1028,1064],{"__ignoreMap":38},[42,960,961,964,966,969,971,974],{"class":44,"line":45},[42,962,963],{"class":506},"polyglotI18nProvider",[42,965,511],{"class":510},[42,967,968],{"class":130},"()",[42,970,177],{"class":176},[42,972,973],{"class":510}," (",[42,975,514],{"class":130},[42,977,978,981,984],{"class":44,"line":123},[42,979,980],{"class":130},"  ...",[42,982,983],{"class":134},"frenchMessages",[42,985,532],{"class":130},[42,987,988,991,993,995,998,1000,1002,1005,1007,1009,1011,1013,1016,1019,1022,1024,1026],{"class":44,"line":157},[42,989,990],{"class":519},"  fougere",[42,992,422],{"class":130},[42,994,131],{"class":130},[42,996,997],{"class":519}," admin",[42,999,422],{"class":130},[42,1001,131],{"class":130},[42,1003,1004],{"class":519}," overview",[42,1006,422],{"class":130},[42,1008,131],{"class":130},[42,1010,746],{"class":519},[42,1012,422],{"class":130},[42,1014,1015],{"class":144}," \"",[42,1017,1018],{"class":51},"Vue d'ensemble",[42,1020,1021],{"class":144},"\"",[42,1023,138],{"class":130},[42,1025,138],{"class":130},[42,1027,633],{"class":130},[42,1029,1030,1033,1035,1037,1039,1041,1043,1046,1048,1050,1053,1055,1057,1060,1062],{"class":44,"line":164},[42,1031,1032],{"class":519},"  post",[42,1034,422],{"class":130},[42,1036,131],{"class":130},[42,1038,746],{"class":519},[42,1040,422],{"class":130},[42,1042,145],{"class":144},[42,1044,1045],{"class":51},"Titre",[42,1047,151],{"class":144},[42,1049,595],{"class":130},[42,1051,1052],{"class":519}," status",[42,1054,422],{"class":130},[42,1056,145],{"class":144},[42,1058,1059],{"class":51},"Statut",[42,1061,151],{"class":144},[42,1063,633],{"class":130},[42,1065,1066,1068,1071,1073,1075,1078,1080],{"class":44,"line":535},[42,1067,651],{"class":130},[42,1069,1070],{"class":510},")",[42,1072,595],{"class":130},[42,1074,145],{"class":144},[42,1076,1077],{"class":51},"fr",[42,1079,151],{"class":144},[42,1081,654],{"class":510},[196,1083,1085],{"id":1084},"the-one-page-that-is-not-a-facade","The one page that is not a facade",[13,1087,1088,1089,1092],{},"Every screen above renders a facade. ",[1090,1091,372],"strong",{}," renders the app:",[32,1094,1099],{"className":1095,"code":1097,"language":1098},[1096],"language-text","catalog  here               1 entity · 1 facade      → blog (12)\nblog     elsewhere          its shape is published by the process that owns it   ← catalog (12)\nsearch   declared, unheard  declared at search.internal:4500 — nothing has answered from it\n","text",[17,1100,1097],{"__ignoreMap":38},[13,1102,1103,1104,1106],{},"It is read from ",[17,1105,377],{},", not from the card: which fronds run in the process the panel talks\nto, which answered from elsewhere, and the calls seen between them. The last line comes from what\nthe config declares: a frond that never answered would otherwise be missing, and a system with a\nnode down would look like a smaller healthy one.",[13,1108,1109,1111,1112,1118],{},[17,1110,377],{}," is served by ",[390,1113,1115],{"href":1114},"\u002Fdocs\u002Frun\u002Fobserve",[17,1116,1117],{},"@fougere\u002Fobservability",". Pointed at an app without\nit, the page says which two lines to add.",[196,1120,1122],{"id":1121},"what-it-will-not-do","What it will not do",[1124,1125,1126,1146,1152,1167],"ul",{},[1127,1128,1129,1132,1133,1137,1138,1141,1142,1145],"li",{},[1090,1130,1131],{},"Remove a resource or an operation."," Hiding it in the browser while the server still serves it\nwould look like a permission and enforce nothing. What one audience may call is a\n",[390,1134,1136],{"href":1135},"\u002Fdocs\u002Fconcepts\u002Fhandler#what-leaves","surface",": point the panel at ",[17,1139,1140],{},"\u002F_fougere\u002Fcall\u002Fadmin"," and the card it reads\nis the restricted one. A ",[468,1143,1144],{},"field"," may be hidden: that changes nothing about what is reachable.",[1127,1147,1148,1151],{},[1090,1149,1150],{},"Write around the checks."," It runs in a browser and reaches only the call endpoint, so every read\nand write it makes goes through validation, presenters and the links around calls.",[1127,1153,1154,1157,1158,1161,1162,1166],{},[1090,1155,1156],{},"Aggregate."," The only aggregate rows answer is ",[17,1159,1160],{},"count",", so the dashboard counts. \"Revenue over\nthirty days\" is an operation you write in a ",[390,1163,1165],{"href":1164},"\u002Fdocs\u002Fconcepts\u002Frepository","repository","; the panel\nshows its result.",[1127,1168,1169,1172,1173,890],{},[1090,1170,1171],{},"Own your pages."," It is a panel for whoever administers the data. The application's own\nscreens stay yours, built on ",[390,1174,1176],{"href":1175},"\u002Fdocs\u002Fserve\u002Fpages","queries and commands",[1178,1179,1180],"style",{},"html pre.shiki code .sV8pK, html code.shiki .sV8pK{--shiki-light:#E2931D;--shiki-default:#C9B6EA;--shiki-dark:#FFCB6B}html pre.shiki code .sN-8n, html code.shiki .sN-8n{--shiki-light:#91B859;--shiki-default:#EE9F6B;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .skXKP, html code.shiki .skXKP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7D8C80;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sK6XW, html code.shiki .sK6XW{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#8FCF86;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s15xx, html code.shiki .s15xx{--shiki-light:#39ADB5;--shiki-default:#A3B0A5;--shiki-dark:#89DDFF}html pre.shiki code .sPEhv, html code.shiki .sPEhv{--shiki-light:#90A4AE;--shiki-default:#DDE5DA;--shiki-dark:#BABED8}html pre.shiki code .sDDC1, html code.shiki .sDDC1{--shiki-light:#39ADB5;--shiki-default:#EE9F6B;--shiki-dark:#89DDFF}html pre.shiki code .scTuO, html code.shiki .scTuO{--shiki-light:#9C3EDA;--shiki-default:#A3B0A5;--shiki-dark:#C792EA}html pre.shiki code .sBZYL, html code.shiki .sBZYL{--shiki-light:#E2931D;--shiki-default:#EFCD8F;--shiki-dark:#FFCB6B}html pre.shiki code .sWI7z, html code.shiki .sWI7z{--shiki-light:#E2931D;--shiki-default:#93CFC0;--shiki-dark:#FFCB6B}html pre.shiki code .s4mR9, html code.shiki .s4mR9{--shiki-light:#6182B8;--shiki-default:#C9B6EA;--shiki-dark:#82AAFF}html pre.shiki code .srlTG, html code.shiki .srlTG{--shiki-light:#90A4AE;--shiki-default:#A3B0A5;--shiki-dark:#BABED8}html pre.shiki code .sHtqg, html code.shiki .sHtqg{--shiki-light:#E53935;--shiki-default:#93CFC0;--shiki-dark:#F07178}html pre.shiki code .slmMI, html code.shiki .slmMI{--shiki-light:#FF5370;--shiki-default:#EE9F6B;--shiki-dark:#FF9CAC}html pre.shiki code .s8ClO, html code.shiki .s8ClO{--shiki-light:#9C3EDA;--shiki-default:#93CFC0;--shiki-dark:#C792EA}html pre.shiki code .sK7Y8, html code.shiki .sK7Y8{--shiki-light:#E53935;--shiki-default:#EE9F6B;--shiki-dark:#F07178}html pre.shiki code .shDUQ, html code.shiki .shDUQ{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#DDE5DA;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sy9f4, html code.shiki .sy9f4{--shiki-light:#90A4AE;--shiki-default:#93CFC0;--shiki-dark:#BABED8}",{"title":38,"searchDepth":123,"depth":123,"links":1182},[1183,1184,1185,1186,1187,1188,1189],{"id":198,"depth":123,"text":199},{"id":397,"depth":123,"text":398},{"id":458,"depth":123,"text":459},{"id":668,"depth":123,"text":669},{"id":938,"depth":123,"text":939},{"id":1084,"depth":123,"text":1085},{"id":1121,"depth":123,"text":1122},"A back-office read from the card, nothing declared twice.","md",[23],"task",{},"\u002Fdocs\u002Fserve\u002Fadmin",{"title":8,"description":1190},"docs\u002F5.serve\u002F4.admin",null,[1200],"handler","HRlwk1nKE5nN97vq-u4Jf5Pli5-gXipkaUxXZ4VV81M",[1203,1206,1209,1211,1214,1217,1220,1223,1226,1232,1237,1242,1246,1250,1254,1258,1262,1266,1270,1274,1279,1283,1287,1290,1292,1296,1300,1304,1307,1311,1315,1319,1323,1327,1331,1335,1339,1342,1345,1348,1351,1354,1357,1360,1363,1366,1369],{"path":1204,"title":1205,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Fentity","Entity",{"path":1207,"title":1208,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Fhandler","Handler",{"path":1164,"title":1210,"uses":1198},"Repository",{"path":1212,"title":1213,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Ffrond","Frond",{"path":1215,"title":1216,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Ffacade","Facade",{"path":1218,"title":1219,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Ffact","Fact",{"path":1221,"title":1222,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Fport","Port",{"path":1224,"title":1225,"uses":1198},"\u002Fdocs\u002Fconcepts\u002Fconfiguration","Configuration",{"path":1227,"title":1228,"uses":1229},"\u002Fdocs\u002Faccess\u002Fauthentication","Authentication",[1230,1231],"port","frond",{"path":1233,"title":1234,"uses":1235},"\u002Fdocs\u002Faccess\u002Fstate","Keep a caller's state",[1236,1200],"configuration",{"path":1238,"title":1239,"uses":1240},"\u002Fdocs\u002Fdata\u002Fsql","SQLite or Postgres",[1241,1236],"entity",{"path":1243,"title":1244,"uses":1245},"\u002Fdocs\u002Fdata\u002Fseveral-databases","Several databases",[1236,1241],{"path":1247,"title":1248,"uses":1249},"\u002Fdocs\u002Fdata\u002Fcomputed-field","A computed field",[1241,1230],{"path":1251,"title":1252,"uses":1253},"\u002Fdocs\u002Fdata\u002Fevolve","Evolve a schema",[1241],{"path":1255,"title":1256,"uses":1257},"\u002Fdocs\u002Fdata\u002Fseeds","Seed data",[1241],{"path":1259,"title":1260,"uses":1261},"\u002Fdocs\u002Fdata\u002Fvalues","Read settings and secrets",[1241,1236],{"path":1263,"title":1264,"uses":1265},"\u002Fdocs\u002Fdata\u002Fmirror","Mirror a source you cannot query",[1165],{"path":1267,"title":1268,"uses":1269},"\u002Fdocs\u002Fdata\u002Ftogether","Two writes as one",[1165],{"path":1271,"title":1272,"uses":1273},"\u002Fdocs\u002Fbehaviour\u002Faround-every-call","Around every call",[1230,1231],{"path":1275,"title":1276,"uses":1277},"\u002Fdocs\u002Fbehaviour\u002Ffinish-a-fact","Finish a fact",[1278],"fact",{"path":1280,"title":1281,"uses":1282},"\u002Fdocs\u002Fserve\u002Frest-graphql","REST, OpenAPI, GraphQL",[1200,1236],{"path":1175,"title":1284,"uses":1285},"Pages: queries and commands",[1200,1286],"facade",{"path":392,"title":1288,"uses":1289},"A form",[1241],{"path":1195,"title":8,"uses":1291},[1200],{"path":1293,"title":1294,"uses":1295},"\u002Fdocs\u002Frun\u002Fdeploy","Deploy a split",[1236,1231],{"path":1297,"title":1298,"uses":1299},"\u002Fdocs\u002Frun\u002Fsecure","Secure calls between processes",[1236,1231],{"path":1301,"title":1302,"uses":1303},"\u002Fdocs\u002Frun\u002Flifecycle","Reload and shut down",[1236],{"path":1114,"title":1305,"uses":1306},"Observe",[1236,1200],{"path":1308,"title":1309,"uses":1310},"\u002Fdocs\u002Frun\u002Fdev-panel","The dev panel",[1200],{"path":1312,"title":1313,"uses":1314},"\u002Fdocs\u002Frun\u002Ftest","Test",[1241,1230],{"path":1316,"title":1317,"uses":1318},"\u002Fdocs\u002Fadopt\u002Fnew-project","Start a project",[1231,1236],{"path":1320,"title":1321,"uses":1322},"\u002Fdocs\u002Fadopt\u002Fexisting-app","Add Fougere to an existing app",[1231,1236],{"path":1324,"title":1325,"uses":1326},"\u002Fdocs\u002Fadopt\u002Fbring-your-schema","Bring your schema",[1241],{"path":1328,"title":1329,"uses":1330},"\u002Fdocs\u002Fadopt\u002Fhosts","Pick a host",[1236],{"path":1332,"title":1333,"uses":1334},"\u002Fdocs\u002Fadopt\u002Fanother-repository","A frond from another repository",[1286,1231],{"path":1336,"title":1337,"uses":1338},"\u002Fdocs\u002Fadopt\u002Fdemos","Demos",[],{"path":1340,"title":1341,"uses":1198},"\u002Fdocs\u002Fextending\u002Fscan","How the scan reads a project",{"path":1343,"title":1344,"uses":1198},"\u002Fdocs\u002Fextending\u002Fwithout-compiler","Boot without the compiler",{"path":1346,"title":1347,"uses":1198},"\u002Fdocs\u002Fextending\u002Fboot","The boot, step by step",{"path":1349,"title":1350,"uses":1198},"\u002Fdocs\u002Fextending\u002Fcard-and-wire","The card and the wire",{"path":1352,"title":1353,"uses":1198},"\u002Fdocs\u002Fextending\u002Fextension-points","Registries and extension points",{"path":1355,"title":1356,"uses":1198},"\u002Fdocs\u002Fextending\u002Fvocabulary","Teach a word",{"path":1358,"title":1359,"uses":1198},"\u002Fdocs\u002Fextending\u002Fextensions","Run code at boot and shutdown",{"path":1361,"title":1362,"uses":1198},"\u002Fdocs\u002Fextending\u002Fsource-adapter","Write a source adapter",{"path":1364,"title":1365,"uses":1198},"\u002Fdocs\u002Fextending\u002Fsurface","Write a surface",{"path":1367,"title":1368,"uses":1198},"\u002Fdocs\u002Fextending\u002Fforeign-frond","A frond in another language",{"path":1370,"title":1371,"uses":1198},"\u002Fdocs","What is Fougere",[1373],{"title":1374,"path":1370,"stem":1375,"children":1376,"page":-1},"Docs","docs",[1377,1379,1400,1409,1430,1439,1451,1468,1485],{"title":1371,"path":1370,"stem":1378},"docs\u002Findex",{"title":1380,"path":1381,"stem":1382,"children":1383,"page":5},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F1.concepts",[1384,1386,1388,1390,1392,1394,1396,1398],{"title":1205,"path":1204,"stem":1385},"docs\u002F1.concepts\u002F1.entity",{"title":1208,"path":1207,"stem":1387},"docs\u002F1.concepts\u002F2.handler",{"title":1210,"path":1164,"stem":1389},"docs\u002F1.concepts\u002F3.repository",{"title":1213,"path":1212,"stem":1391},"docs\u002F1.concepts\u002F4.frond",{"title":1216,"path":1215,"stem":1393},"docs\u002F1.concepts\u002F5.facade",{"title":1219,"path":1218,"stem":1395},"docs\u002F1.concepts\u002F6.fact",{"title":1222,"path":1221,"stem":1397},"docs\u002F1.concepts\u002F7.port",{"title":1225,"path":1224,"stem":1399},"docs\u002F1.concepts\u002F8.configuration",{"title":1401,"path":1402,"stem":1403,"children":1404,"page":5},"Access","\u002Fdocs\u002Faccess","docs\u002F2.access",[1405,1407],{"title":1228,"path":1227,"stem":1406},"docs\u002F2.access\u002F1.authentication",{"title":1234,"path":1233,"stem":1408},"docs\u002F2.access\u002F2.state",{"title":1410,"path":1411,"stem":1412,"children":1413,"page":5},"Data","\u002Fdocs\u002Fdata","docs\u002F3.data",[1414,1416,1418,1420,1422,1424,1426,1428],{"title":1239,"path":1238,"stem":1415},"docs\u002F3.data\u002F1.sql",{"title":1244,"path":1243,"stem":1417},"docs\u002F3.data\u002F2.several-databases",{"title":1248,"path":1247,"stem":1419},"docs\u002F3.data\u002F3.computed-field",{"title":1252,"path":1251,"stem":1421},"docs\u002F3.data\u002F4.evolve",{"title":1256,"path":1255,"stem":1423},"docs\u002F3.data\u002F5.seeds",{"title":1260,"path":1259,"stem":1425},"docs\u002F3.data\u002F6.values",{"title":1264,"path":1263,"stem":1427},"docs\u002F3.data\u002F7.mirror",{"title":1268,"path":1267,"stem":1429},"docs\u002F3.data\u002F8.together",{"title":1431,"path":1432,"stem":1433,"children":1434,"page":5},"Behaviour","\u002Fdocs\u002Fbehaviour","docs\u002F4.behaviour",[1435,1437],{"title":1272,"path":1271,"stem":1436},"docs\u002F4.behaviour\u002F1.around-every-call",{"title":1276,"path":1275,"stem":1438},"docs\u002F4.behaviour\u002F2.finish-a-fact",{"title":1440,"path":1441,"stem":1442,"children":1443,"page":5},"Serve","\u002Fdocs\u002Fserve","docs\u002F5.serve",[1444,1446,1448,1450],{"title":1281,"path":1280,"stem":1445},"docs\u002F5.serve\u002F1.rest-graphql",{"title":1284,"path":1175,"stem":1447},"docs\u002F5.serve\u002F2.pages",{"title":1288,"path":392,"stem":1449},"docs\u002F5.serve\u002F3.forms",{"title":8,"path":1195,"stem":1197},{"title":1452,"path":1453,"stem":1454,"children":1455,"page":5},"Run","\u002Fdocs\u002Frun","docs\u002F6.run",[1456,1458,1460,1462,1464,1466],{"title":1294,"path":1293,"stem":1457},"docs\u002F6.run\u002F1.deploy",{"title":1298,"path":1297,"stem":1459},"docs\u002F6.run\u002F2.secure",{"title":1302,"path":1301,"stem":1461},"docs\u002F6.run\u002F3.lifecycle",{"title":1305,"path":1114,"stem":1463},"docs\u002F6.run\u002F4.observe",{"title":1309,"path":1308,"stem":1465},"docs\u002F6.run\u002F5.dev-panel",{"title":1313,"path":1312,"stem":1467},"docs\u002F6.run\u002F6.test",{"title":1469,"path":1470,"stem":1471,"children":1472,"page":5},"Adopt","\u002Fdocs\u002Fadopt","docs\u002F7.adopt",[1473,1475,1477,1479,1481,1483],{"title":1317,"path":1316,"stem":1474},"docs\u002F7.adopt\u002F1.new-project",{"title":1321,"path":1320,"stem":1476},"docs\u002F7.adopt\u002F2.existing-app",{"title":1325,"path":1324,"stem":1478},"docs\u002F7.adopt\u002F3.bring-your-schema",{"title":1329,"path":1328,"stem":1480},"docs\u002F7.adopt\u002F4.hosts",{"title":1333,"path":1332,"stem":1482},"docs\u002F7.adopt\u002F5.another-repository",{"title":1337,"path":1336,"stem":1484},"docs\u002F7.adopt\u002F6.demos",{"title":1486,"path":1487,"stem":1488,"children":1489,"page":5},"Extending","\u002Fdocs\u002Fextending","docs\u002F8.extending",[1490,1492,1494,1496,1498,1500,1502,1504,1506,1508],{"title":1341,"path":1340,"stem":1491},"docs\u002F8.extending\u002F1.scan",{"title":1344,"path":1343,"stem":1493},"docs\u002F8.extending\u002F10.without-compiler",{"title":1347,"path":1346,"stem":1495},"docs\u002F8.extending\u002F2.boot",{"title":1350,"path":1349,"stem":1497},"docs\u002F8.extending\u002F3.card-and-wire",{"title":1353,"path":1352,"stem":1499},"docs\u002F8.extending\u002F4.extension-points",{"title":1356,"path":1355,"stem":1501},"docs\u002F8.extending\u002F5.vocabulary",{"title":1359,"path":1358,"stem":1503},"docs\u002F8.extending\u002F6.extensions",{"title":1362,"path":1361,"stem":1505},"docs\u002F8.extending\u002F7.source-adapter",{"title":1365,"path":1364,"stem":1507},"docs\u002F8.extending\u002F8.surface",{"title":1368,"path":1367,"stem":1509},"docs\u002F8.extending\u002F9.foreign-frond",1794396614653]