[{"data":1,"prerenderedAt":1237},["ShallowReactive",2],{"docs-nav:en":3,"docs:\u002Fdocs\u002Fclient\u002Fadmin":186},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,24,28,50,75,120,145],{"title":10,"path":6,"stem":11},"What is Fougere","docs\u002Findex",{"title":13,"path":14,"stem":15},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",{"title":17,"path":18,"stem":19},"An app you already have","\u002Fdocs\u002Fexisting-app","docs\u002F02.existing-app",{"title":21,"path":22,"stem":23},"Bring your schema","\u002Fdocs\u002Fbring-your-schema","docs\u002F03.bring-your-schema",{"title":25,"path":26,"stem":27},"The CLI","\u002Fdocs\u002Fcli","docs\u002F04.cli",{"title":29,"path":30,"stem":31,"children":32,"page":49},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[33,37,41,45],{"title":34,"path":35,"stem":36},"Philosophy","\u002Fdocs\u002Fconcepts\u002Fphilosophy","docs\u002F2.concepts\u002F1.philosophy",{"title":38,"path":39,"stem":40},"The Frond","\u002Fdocs\u002Fconcepts\u002Ffrond","docs\u002F2.concepts\u002F2.frond",{"title":42,"path":43,"stem":44},"The shortest path","\u002Fdocs\u002Fconcepts\u002Fshortest-path","docs\u002F2.concepts\u002F3.shortest-path",{"title":46,"path":47,"stem":48},"The base","\u002Fdocs\u002Fconcepts\u002Fthe-base","docs\u002F2.concepts\u002F4.the-base",false,{"title":51,"path":52,"stem":53,"children":54,"page":49},"Schema","\u002Fdocs\u002Fschema","docs\u002F3.schema",[55,59,63,67,71],{"title":56,"path":57,"stem":58},"Entities","\u002Fdocs\u002Fschema\u002Fentities","docs\u002F3.schema\u002F1.entities",{"title":60,"path":61,"stem":62},"Views","\u002Fdocs\u002Fschema\u002Fviews","docs\u002F3.schema\u002F2.views",{"title":64,"path":65,"stem":66},"The identity card","\u002Fdocs\u002Fschema\u002Fcard","docs\u002F3.schema\u002F3.card",{"title":68,"path":69,"stem":70},"Standard Schema","\u002Fdocs\u002Fschema\u002Fstandard-schema","docs\u002F3.schema\u002F4.standard-schema",{"title":72,"path":73,"stem":74},"How a schema moves","\u002Fdocs\u002Fschema\u002Fevolution","docs\u002F3.schema\u002F5.evolution",{"title":76,"path":77,"stem":78,"children":79,"page":49},"Business","\u002Fdocs\u002Fbusiness","docs\u002F4.business",[80,84,88,92,96,100,104,108,112,116],{"title":81,"path":82,"stem":83},"Handlers","\u002Fdocs\u002Fbusiness\u002Fhandlers","docs\u002F4.business\u002F1.handlers",{"title":85,"path":86,"stem":87},"Ports","\u002Fdocs\u002Fbusiness\u002Fports","docs\u002F4.business\u002F10.ports",{"title":89,"path":90,"stem":91},"Presenters","\u002Fdocs\u002Fbusiness\u002Fpresenters","docs\u002F4.business\u002F2.presenters",{"title":93,"path":94,"stem":95},"Collectors","\u002Fdocs\u002Fbusiness\u002Fcollectors","docs\u002F4.business\u002F3.collectors",{"title":97,"path":98,"stem":99},"Errors","\u002Fdocs\u002Fbusiness\u002Ferrors","docs\u002F4.business\u002F4.errors",{"title":101,"path":102,"stem":103},"Seeds","\u002Fdocs\u002Fbusiness\u002Fseeds","docs\u002F4.business\u002F5.seeds",{"title":105,"path":106,"stem":107},"Facts","\u002Fdocs\u002Fbusiness\u002Ffacts","docs\u002F4.business\u002F6.facts",{"title":109,"path":110,"stem":111},"Storage","\u002Fdocs\u002Fbusiness\u002Fstorage","docs\u002F4.business\u002F7.storage",{"title":113,"path":114,"stem":115},"Writes that stand or fall as one","\u002Fdocs\u002Fbusiness\u002Ftogether","docs\u002F4.business\u002F8.together",{"title":117,"path":118,"stem":119},"Repositories","\u002Fdocs\u002Fbusiness\u002Frepositories","docs\u002F4.business\u002F9.repositories",{"title":121,"path":122,"stem":123,"children":124,"page":49},"Client","\u002Fdocs\u002Fclient","docs\u002F5.client",[125,129,133,137,141],{"title":126,"path":127,"stem":128},"Queries & commands","\u002Fdocs\u002Fclient\u002Fqueries-commands","docs\u002F5.client\u002F1.queries-commands",{"title":130,"path":131,"stem":132},"Forms","\u002Fdocs\u002Fclient\u002Fforms","docs\u002F5.client\u002F2.forms",{"title":134,"path":135,"stem":136},"Session","\u002Fdocs\u002Fclient\u002Fsession","docs\u002F5.client\u002F3.session",{"title":138,"path":139,"stem":140},"invoke","\u002Fdocs\u002Fclient\u002Finvoke","docs\u002F5.client\u002F4.invoke",{"title":142,"path":143,"stem":144},"Back-office","\u002Fdocs\u002Fclient\u002Fadmin","docs\u002F5.client\u002F5.admin",{"title":146,"path":147,"stem":148,"children":149,"page":49},"Infrastructure","\u002Fdocs\u002Finfra","docs\u002F6.infra",[150,154,158,162,166,170,174,178,182],{"title":151,"path":152,"stem":153},"The gradient","\u002Fdocs\u002Finfra\u002Fgradient","docs\u002F6.infra\u002F1.gradient",{"title":155,"path":156,"stem":157},"Surfaces — REST & GraphQL","\u002Fdocs\u002Finfra\u002Fsurfaces","docs\u002F6.infra\u002F2.surfaces",{"title":159,"path":160,"stem":161},"Deployment","\u002Fdocs\u002Finfra\u002Fdeployment","docs\u002F6.infra\u002F3.deployment",{"title":163,"path":164,"stem":165},"Hosts","\u002Fdocs\u002Finfra\u002Fhosts","docs\u002F6.infra\u002F4.hosts",{"title":167,"path":168,"stem":169},"Sources","\u002Fdocs\u002Finfra\u002Fsources","docs\u002F6.infra\u002F5.sources",{"title":171,"path":172,"stem":173},"Lifecycle","\u002Fdocs\u002Finfra\u002Flifecycle","docs\u002F6.infra\u002F6.lifecycle",{"title":175,"path":176,"stem":177},"Identity across Fronds","\u002Fdocs\u002Finfra\u002Fidentity","docs\u002F6.infra\u002F7.identity",{"title":179,"path":180,"stem":181},"Observability","\u002Fdocs\u002Finfra\u002Fobservability","docs\u002F6.infra\u002F8.observability",{"title":183,"path":184,"stem":185},"Testing","\u002Fdocs\u002Finfra\u002Ftesting","docs\u002F6.infra\u002F9.testing",{"id":187,"title":142,"body":188,"description":1232,"extension":1233,"meta":1234,"navigation":267,"path":143,"seo":1235,"stem":144,"__hash__":1236},"docs_en\u002Fdocs\u002F5.client\u002F5.admin.md",{"type":189,"value":190,"toc":1222},"minimark",[191,195,213,216,244,275,282,287,444,456,460,463,506,517,521,533,722,749,753,756,889,907,932,936,953,1084,1088,1094,1102,1120,1129,1133,1185,1189,1212,1218],[192,193,142],"h1",{"id":194},"back-office",[196,197,198,199,203,204,208,209,212],"p",{},"A back-office asks four questions: which subjects exist, what a row shows, what a form\nsupplies, and which verbs are allowed. ",[200,201,202],"strong",{},"The identity card already answers all four",", so\n",[205,206,207],"code",{},"@fougere\u002Fadmin"," generates nothing and declares nothing — it reads ",[205,210,211],{},"rpc.discover"," at load\ntime and renders the answer.",[196,214,215],{},"That is the difference from a CMS. Payload, Strapi and Directus sell the derivation of an\nadmin from a content declaration; here the declaration was already there, doing five other\njobs, and the panel is its sixth projection.",[217,218,223],"pre",{"className":219,"code":220,"language":221,"meta":222,"style":222},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","pnpm add @fougere\u002Fadmin react-admin\n","bash","",[205,224,225],{"__ignoreMap":222},[226,227,230,234,238,241],"span",{"class":228,"line":229},"line",1,[226,231,233],{"class":232},"sbgvK","pnpm",[226,235,237],{"class":236},"s_sjI"," add",[226,239,240],{"class":236}," @fougere\u002Fadmin",[226,242,243],{"class":236}," react-admin\n",[217,245,249],{"className":246,"code":247,"language":248,"meta":222,"style":222},"language-tsx shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F app\u002Fadmin.tsx — the whole file\nimport { FougereAdmin } from '@fougere\u002Fadmin\u002Freact';\n\nexport default () => \u003CFougereAdmin \u002F>;\n","tsx",[205,250,251,256,262,269],{"__ignoreMap":222},[226,252,253],{"class":228,"line":229},[226,254,255],{},"\u002F\u002F app\u002Fadmin.tsx — the whole file\n",[226,257,259],{"class":228,"line":258},2,[226,260,261],{},"import { FougereAdmin } from '@fougere\u002Fadmin\u002Freact';\n",[226,263,265],{"class":228,"line":264},3,[226,266,268],{"emptyLinePlaceholder":267},true,"\n",[226,270,272],{"class":228,"line":271},4,[226,273,274],{},"export default () => \u003CFougereAdmin \u002F>;\n",[196,276,277,278,281],{},"Three lines, every entity, forever. A new ",[205,279,280],{},"class Invoice extends entity({…})"," appears in\nthe menu on the next load, because the card grew a door — not because a file was written.",[283,284,286],"h2",{"id":285},"what-each-screen-is-read-from","What each screen is read from",[288,289,290,306],"table",{},[291,292,293],"thead",{},[294,295,296,300,303],"tr",{},[297,298,299],"th",{},"Screen",[297,301,302],{},"Read from",[297,304,305],{},"Function",[307,308,309,323,339,355,381,398,415,431],"tbody",{},[294,310,311,315,320],{},[312,313,314],"td",{},"The menu",[312,316,317],{},[205,318,319],{},"card.fronds[].doors[]",[312,321,322],{},"a door with no schema is not furniture",[294,324,325,328,334],{},[312,326,327],{},"A list's columns",[312,329,330,333],{},[205,331,332],{},"Visibility.output"," + the shape",[312,335,336],{},[205,337,338],{},"tableColumnsOf",[294,340,341,344,350],{},[312,342,343],{},"A form's inputs",[312,345,346,349],{},[205,347,348],{},"Visibility.input"," + the lifecycle axis",[312,351,352],{},[205,353,354],{},"formFieldsOf",[294,356,357,360,376],{},[312,358,359],{},"Its bounds",[312,361,362,365,366,369,370,369,373],{},[205,363,364],{},"shape"," → ",[205,367,368],{},"minlength",", ",[205,371,372],{},"max",[205,374,375],{},"pattern",[312,377,378],{},[205,379,380],{},"field.attrs",[294,382,383,386,393],{},[312,384,385],{},"A row's identity",[312,387,388,389,392],{},"the ",[205,390,391],{},"primary"," role",[312,394,395],{},[205,396,397],{},"FieldSet.of(fields).primary",[294,399,400,403,408],{},[312,401,402],{},"The buttons",[312,404,405],{},[205,406,407],{},"door.ops",[312,409,410,411,414],{},"no ",[205,412,413],{},"create"," op, no create button",[294,416,417,420,425],{},[312,418,419],{},"A refusal",[312,421,422],{},[205,423,424],{},"VALIDATION_FAILED",[312,426,427,430],{},[205,428,429],{},"errorsByField",", per field",[294,432,433,436,441],{},[312,434,435],{},"Topology",[312,437,438],{},[205,439,440],{},"rpc.topology",[312,442,443],{},"the one screen the card does not answer",[196,445,446,448,449,451,452,455],{},[205,447,338],{}," and ",[205,450,354],{}," are duals of one another and are the same pair\n",[453,454,130],"a",{"href":131}," already uses — one reads what may leave, the other what a\nclient may supply. The panel adds no third reading.",[283,457,459],{"id":458},"the-gradient-reaches-it","The gradient reaches it",[196,461,462],{},"The panel talks to the call endpoint and knows nothing else. So this changes nothing about\nit:",[217,464,468],{"className":465,"code":466,"language":467,"meta":222,"style":222},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F fougere.config.ts\nremotes: { billing: 'https:\u002F\u002Fbilling.internal' }\n","ts",[205,469,470,476],{"__ignoreMap":222},[226,471,472],{"class":228,"line":229},[226,473,475],{"class":474},"sutJx","\u002F\u002F fougere.config.ts\n",[226,477,478,481,485,488,491,493,497,500,503],{"class":228,"line":258},[226,479,480],{"class":232},"remotes",[226,482,484],{"class":483},"sP7_E",":",[226,486,487],{"class":483}," {",[226,489,490],{"class":232}," billing",[226,492,484],{"class":483},[226,494,496],{"class":495},"sjJ54"," '",[226,498,499],{"class":236},"https:\u002F\u002Fbilling.internal",[226,501,502],{"class":495},"'",[226,504,505],{"class":483}," }\n",[196,507,508,509,512,513,516],{},"The ",[205,510,511],{},"invoice"," door moves to another process, the card still announces it, the same build\nrenders the same screens. ",[200,514,515],{},"A headless CMS cannot do this"," — its admin is bound to its\nown API by construction, and the process boundary is the product.",[283,518,520],{"id":519},"facets-declared-never-guessed","Facets — declared, never guessed",[196,522,523,524,527,528,532],{},"Some things a renderer wants are not in the shape. ",[205,525,526],{},"oneOf('draft', 'published')"," says the\nset is closed; it never says which member means ",[529,530,531],"em",{},"published",". That is a real statement\nabout a domain, and a human makes it:",[217,534,536],{"className":465,"code":535,"language":467,"meta":222,"style":222},"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",[205,537,538,565,569,581,599,610,620,637,701,707,713],{"__ignoreMap":222},[226,539,540,544,546,550,553,556,558,560,562],{"class":228,"line":229},[226,541,543],{"class":542},"sVHd0","import",[226,545,487],{"class":483},[226,547,549],{"class":548},"su5hD"," defineAdminExtension",[226,551,552],{"class":483}," }",[226,554,555],{"class":542}," from",[226,557,496],{"class":495},[226,559,207],{"class":236},[226,561,502],{"class":495},[226,563,564],{"class":483},";\n",[226,566,567],{"class":228,"line":258},[226,568,268],{"emptyLinePlaceholder":267},[226,570,571,575,578],{"class":228,"line":264},[226,572,574],{"class":573},"sGLFI","defineAdminExtension",[226,576,577],{"class":548},"(",[226,579,580],{"class":483},"{\n",[226,582,583,587,589,591,594,596],{"class":228,"line":271},[226,584,586],{"class":585},"skxfh","  resource",[226,588,484],{"class":483},[226,590,496],{"class":495},[226,592,593],{"class":236},"post",[226,595,502],{"class":495},[226,597,598],{"class":483},",\n",[226,600,602,605,607],{"class":228,"line":601},5,[226,603,604],{"class":585},"  facets",[226,606,484],{"class":483},[226,608,609],{"class":483}," {\n",[226,611,613,616,618],{"class":228,"line":612},6,[226,614,615],{"class":585},"    editorial",[226,617,484],{"class":483},[226,619,609],{"class":483},[226,621,623,626,628,630,633,635],{"class":228,"line":622},7,[226,624,625],{"class":585},"      title",[226,627,484],{"class":483},[226,629,496],{"class":495},[226,631,632],{"class":236},"title",[226,634,502],{"class":495},[226,636,598],{"class":483},[226,638,640,643,645,647,650,652,654,657,659,662,665,667,670,672,675,677,680,682,685,687,689,691,693,695,698],{"class":228,"line":639},8,[226,641,642],{"class":585},"      state",[226,644,484],{"class":483},[226,646,487],{"class":483},[226,648,649],{"class":585}," field",[226,651,484],{"class":483},[226,653,496],{"class":495},[226,655,656],{"class":236},"status",[226,658,502],{"class":495},[226,660,661],{"class":483},",",[226,663,664],{"class":585}," draft",[226,666,484],{"class":483},[226,668,669],{"class":548}," [",[226,671,502],{"class":495},[226,673,674],{"class":236},"draft",[226,676,502],{"class":495},[226,678,679],{"class":548},"]",[226,681,661],{"class":483},[226,683,684],{"class":585}," published",[226,686,484],{"class":483},[226,688,669],{"class":548},[226,690,502],{"class":495},[226,692,531],{"class":236},[226,694,502],{"class":495},[226,696,697],{"class":548},"] ",[226,699,700],{"class":483},"},\n",[226,702,704],{"class":228,"line":703},9,[226,705,706],{"class":483},"    },\n",[226,708,710],{"class":228,"line":709},10,[226,711,712],{"class":483},"  },\n",[226,714,716,719],{"class":228,"line":715},11,[226,717,718],{"class":483},"}",[226,720,721],{"class":548},")\n",[196,723,724,725,728,729,369,731,369,733,736,737,740,741,744,745,748],{},"Nothing is inferred, and that is deliberate. An earlier version read the field ",[529,726,727],{},"names"," —\n",[205,730,632],{},[205,732,656],{},[205,734,735],{},"['draft', 'pending', 'review']"," — and an entity spelling ",[205,738,739],{},"titre"," or\n",[205,742,743],{},"brouillon"," lost its facet with no message. Fougere recognises a field by its ",[200,746,747],{},"form",",\nnever by a word, and a silent wrong answer is worse than an absent one. With no facet\ndeclared, the derived table is still the whole back-office.",[283,750,752],{"id":751},"extensions-are-deltas","Extensions are deltas",[196,754,755],{},"An extension names only what it changes. It never snapshots a resource, so a field added\nto the entity tomorrow still appears:",[217,757,759],{"className":465,"code":758,"language":467,"meta":222,"style":222},"defineAdminExtension({\n  resource: 'post',\n  label: 'Articles',\n  fields: { internalNote: { hidden: true }, title: { label: 'Headline' } },\n  operations: { publish: { confirm: 'Publish this article?' } },\n})\n",[205,760,761,769,783,799,851,883],{"__ignoreMap":222},[226,762,763,765,767],{"class":228,"line":229},[226,764,574],{"class":573},[226,766,577],{"class":548},[226,768,580],{"class":483},[226,770,771,773,775,777,779,781],{"class":228,"line":258},[226,772,586],{"class":585},[226,774,484],{"class":483},[226,776,496],{"class":495},[226,778,593],{"class":236},[226,780,502],{"class":495},[226,782,598],{"class":483},[226,784,785,788,790,792,795,797],{"class":228,"line":264},[226,786,787],{"class":585},"  label",[226,789,484],{"class":483},[226,791,496],{"class":495},[226,793,794],{"class":236},"Articles",[226,796,502],{"class":495},[226,798,598],{"class":483},[226,800,801,804,806,808,811,813,815,818,820,824,827,830,832,834,837,839,841,844,846,848],{"class":228,"line":271},[226,802,803],{"class":585},"  fields",[226,805,484],{"class":483},[226,807,487],{"class":483},[226,809,810],{"class":585}," internalNote",[226,812,484],{"class":483},[226,814,487],{"class":483},[226,816,817],{"class":585}," hidden",[226,819,484],{"class":483},[226,821,823],{"class":822},"syTEX"," true",[226,825,826],{"class":483}," },",[226,828,829],{"class":585}," title",[226,831,484],{"class":483},[226,833,487],{"class":483},[226,835,836],{"class":585}," label",[226,838,484],{"class":483},[226,840,496],{"class":495},[226,842,843],{"class":236},"Headline",[226,845,502],{"class":495},[226,847,552],{"class":483},[226,849,850],{"class":483}," },\n",[226,852,853,856,858,860,863,865,867,870,872,874,877,879,881],{"class":228,"line":601},[226,854,855],{"class":585},"  operations",[226,857,484],{"class":483},[226,859,487],{"class":483},[226,861,862],{"class":585}," publish",[226,864,484],{"class":483},[226,866,487],{"class":483},[226,868,869],{"class":585}," confirm",[226,871,484],{"class":483},[226,873,496],{"class":495},[226,875,876],{"class":236},"Publish this article?",[226,878,502],{"class":495},[226,880,552],{"class":483},[226,882,850],{"class":483},[226,884,885,887],{"class":228,"line":612},[226,886,718],{"class":483},[226,888,721],{"class":548},[196,890,891,892,369,895,369,898,369,901,369,904,484],{},"For anything finer, one renderer replaces one field, and every React Admin prop still\nworks — ",[205,893,894],{},"theme",[205,896,897],{},"layout",[205,899,900],{},"authProvider",[205,902,903],{},"i18nProvider",[205,905,906],{},"dashboard",[217,908,910],{"className":246,"code":909,"language":248,"meta":222,"style":222},"\u003CFougereAdmin\n  renderers={{ fields: { 'user.role': ({ column }) => \u003CChipField source={column.name} \u002F> } }}\n  resourceComponents={{ post: { list: MyPostList } }}\n\u002F>\n",[205,911,912,917,922,927],{"__ignoreMap":222},[226,913,914],{"class":228,"line":229},[226,915,916],{},"\u003CFougereAdmin\n",[226,918,919],{"class":228,"line":258},[226,920,921],{},"  renderers={{ fields: { 'user.role': ({ column }) => \u003CChipField source={column.name} \u002F> } }}\n",[226,923,924],{"class":228,"line":264},[226,925,926],{},"  resourceComponents={{ post: { list: MyPostList } }}\n",[226,928,929],{"class":228,"line":271},[226,930,931],{},"\u002F>\n",[283,933,935],{"id":934},"it-speaks-no-language","It speaks no language",[196,937,938,939,942,943,946,947,949,950,952],{},"Every visible sentence goes through a key: ",[205,940,941],{},"fougere.admin.*"," for the panel's own widgets,\n",[205,944,945],{},"entity.field"," for a field — the convention ",[205,948,354],{}," states, with the derived name\nas its fallback. So an untranslated admin is English, and a ",[205,951,903],{}," filling those\nkeys is the whole translation.",[217,954,956],{"className":465,"code":955,"language":467,"meta":222,"style":222},"polyglotI18nProvider(() => ({\n  ...frenchMessages,\n  fougere: { admin: { overview: { title: \"Vue d'ensemble\" } } },\n  post: { title: 'Titre', status: 'Statut' },\n}), 'fr')\n",[205,957,958,977,988,1030,1066],{"__ignoreMap":222},[226,959,960,963,965,968,972,975],{"class":228,"line":229},[226,961,962],{"class":573},"polyglotI18nProvider",[226,964,577],{"class":548},[226,966,967],{"class":483},"()",[226,969,971],{"class":970},"sbsja"," =>",[226,973,974],{"class":548}," (",[226,976,580],{"class":483},[226,978,979,983,986],{"class":228,"line":258},[226,980,982],{"class":981},"smGrS","  ...",[226,984,985],{"class":548},"frenchMessages",[226,987,598],{"class":483},[226,989,990,993,995,997,1000,1002,1004,1007,1009,1011,1013,1015,1018,1021,1024,1026,1028],{"class":228,"line":264},[226,991,992],{"class":585},"  fougere",[226,994,484],{"class":483},[226,996,487],{"class":483},[226,998,999],{"class":585}," admin",[226,1001,484],{"class":483},[226,1003,487],{"class":483},[226,1005,1006],{"class":585}," overview",[226,1008,484],{"class":483},[226,1010,487],{"class":483},[226,1012,829],{"class":585},[226,1014,484],{"class":483},[226,1016,1017],{"class":495}," \"",[226,1019,1020],{"class":236},"Vue d'ensemble",[226,1022,1023],{"class":495},"\"",[226,1025,552],{"class":483},[226,1027,552],{"class":483},[226,1029,850],{"class":483},[226,1031,1032,1035,1037,1039,1041,1043,1045,1048,1050,1052,1055,1057,1059,1062,1064],{"class":228,"line":271},[226,1033,1034],{"class":585},"  post",[226,1036,484],{"class":483},[226,1038,487],{"class":483},[226,1040,829],{"class":585},[226,1042,484],{"class":483},[226,1044,496],{"class":495},[226,1046,1047],{"class":236},"Titre",[226,1049,502],{"class":495},[226,1051,661],{"class":483},[226,1053,1054],{"class":585}," status",[226,1056,484],{"class":483},[226,1058,496],{"class":495},[226,1060,1061],{"class":236},"Statut",[226,1063,502],{"class":495},[226,1065,850],{"class":483},[226,1067,1068,1070,1073,1075,1077,1080,1082],{"class":228,"line":601},[226,1069,718],{"class":483},[226,1071,1072],{"class":548},")",[226,1074,661],{"class":483},[226,1076,496],{"class":495},[226,1078,1079],{"class":236},"fr",[226,1081,502],{"class":495},[226,1083,721],{"class":548},[283,1085,1087],{"id":1086},"the-one-page-that-is-not-a-door","The one page that is not a door",[196,1089,1090,1091,1093],{},"Every screen above renders a door. ",[200,1092,435],{}," renders the app:",[217,1095,1100],{"className":1096,"code":1098,"language":1099},[1097],"language-text","catalog  here       1 entity · 1 door      → blog (12)\nblog     elsewhere  its shape is published by the process that owns it   ← catalog (12)\n","text",[205,1101,1098],{"__ignoreMap":222},[196,1103,1104,1105,1107,1108,1111,1112,1115,1116,1119],{},"It is read from ",[205,1106,440],{},", not from the card — the card says what a process ",[529,1109,1110],{},"hosts",",\nthis says what shape it is in: which Fronds run in the process the panel is talking to,\nwhich answered from somewhere else, and every call path observed between them. Nothing in\nit is declared: a Frond is remote because it ",[529,1113,1114],{},"answered",", never because ",[205,1117,1118],{},"remotes:"," said so.",[196,1121,1122,1123,1128],{},"That op is served by ",[453,1124,1125],{"href":180},[205,1126,1127],{},"@fougere\u002Fobservability",", so a panel\npointed at an app that does not observe itself gets a refusal — and the page says which two\nlines are missing. The menu entry stays either way: hiding it would hide the one place that\ncan explain the absence.",[283,1130,1132],{"id":1131},"what-it-will-not-do","What it will not do",[1134,1135,1136,1155,1161,1175],"ul",{},[1137,1138,1139,1142,1143,1146,1147,1150,1151,1154],"li",{},[200,1140,1141],{},"Remove a resource or an operation."," Hiding a door in the browser while the façade\nstill serves it reads as a permission and enforces nothing. What a door serves to one\naudience is what a ",[453,1144,1145],{"href":156},"surface"," states — point the panel at\n",[205,1148,1149],{},"\u002F_fougere\u002Fcall\u002Fadmin"," and the card answers restricted. A ",[529,1152,1153],{},"field"," may still be hidden:\nthat changes nothing about what is reachable.",[1137,1156,1157,1160],{},[200,1158,1159],{},"Write outside the façade."," It runs in a browser, so it can only reach the call\nendpoint — judges, presenters and middlewares are on the path of every read and write it\nmakes. This is a consequence, not a precaution.",[1137,1162,1163,1166,1167,1170,1171,1174],{},[200,1164,1165],{},"Aggregate."," Storage's only aggregate is ",[205,1168,1169],{},"count",", so the dashboard counts rows and\nsays so. \"Revenue over thirty days\" is an operation to write, in a\n",[453,1172,1173],{"href":118},"repository","; the panel renders its result, it does not\ninvent the query.",[1137,1176,1177,1180,1181,1184],{},[200,1178,1179],{},"Own your pages."," It is a panel for whoever administers the data. The application's own\nscreens stay yours, built on ",[453,1182,1183],{"href":127},"queries and commands",".",[283,1186,1188],{"id":1187},"one-known-gap","One known gap",[196,1190,1191,1192,1195,1196,1199,1200,1203,1204,1207,1208,1211],{},"A list's ",[205,1193,1194],{},"total"," does not survive the wire: ",[205,1197,1198],{},"ListResult"," extends ",[205,1201,1202],{},"Array",", and\n",[205,1205,1206],{},"JSON.stringify"," drops an array's properties. The provider does not depend on it — it asks\nfor one row more than the page needs and reports ",[205,1209,1210],{},"pageInfo"," — so pagination is exact.\nA row count in a header may be absent under a split.",[196,1213,1214,1215,1217],{},"Next: ",[453,1216,151],{"href":152}," — moving a Frond out of process.",[1219,1220,1221],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":222,"searchDepth":258,"depth":258,"links":1223},[1224,1225,1226,1227,1228,1229,1230,1231],{"id":285,"depth":258,"text":286},{"id":458,"depth":258,"text":459},{"id":519,"depth":258,"text":520},{"id":751,"depth":258,"text":752},{"id":934,"depth":258,"text":935},{"id":1086,"depth":258,"text":1087},{"id":1131,"depth":258,"text":1132},{"id":1187,"depth":258,"text":1188},"A React Admin panel derived from the identity card — no file generated, no entity declared twice, and the same screens whether the frond is in this process or behind an address.","md",{},{"title":142,"description":1232},"DG6sRcxBMpHS3h3gbTzBFtb4TPcdZbMipcdlGi75UYQ",1788560231315]