[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"cw:fronds\u002Fblog\u002Fentities\u002FPost.ts":3,"cw:fronds\u002Fblog\u002Fhandlers\u002FPostHandler.ts":4,"cw:app\u002Fpages\u002Fblog\u002Findex.vue":5,"cw:demos\u002Frust-frond — the TS consumer's output":6,"cw:your-nuxt-app\u002F — 4 files":7,"cw:your-fougere-app\u002F — 1 file":8,"cw:audit-prompt.md":9},"\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">class\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> Post\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> entity\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  id: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">primary\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  slug: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({ min: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, max: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">80\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  title: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({ min: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, max: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">160\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  authorId: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">readOnly\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">()),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  status: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">readOnly\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">oneOf\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'draft'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'published'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">    { default: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'draft'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> })),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  publishedAt: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">readOnly\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">optional\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">date\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">())),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">}) {}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">class\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> PostHandler\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> Crud\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(Post) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">  async\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> publish\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> string\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">user\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">:\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> User\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> |\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> null\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">!\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">user) \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">throw\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> new\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> FougereError\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      code: ErrorCode.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">UNAUTHORIZED\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F* … *\u002F\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">    \u002F\u002F author-only, draft-only — then realize:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> this\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">.orm.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">update\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(id, {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      status: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'published'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      publishedAt: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">new\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> Date\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">toISOString\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">    });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> Post \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> '@frond\u002Fblog\u002Fentities\u002FPost'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">items\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> } \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> await\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> useQuery\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(Post, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'list'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> publish\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> useCommand\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(Post, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'publish'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">await\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> publish.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">execute\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({ params: { id } });\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F → every mounted query on Post revalidates\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">$\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> npx\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> tsx\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> consumer.ts\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">✗\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> couleur\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">  —\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> Unknown\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> field\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">✗\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> celsius\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">  —\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> 250\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> is\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> greater\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> than\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> 80.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">✗\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> checksum\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> —\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> Read-only\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">✗\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> label\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">    —\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> String\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> is\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> too\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\"> short\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> (1 \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> 2\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">).\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F schemas\u002Fpost.ts — the shape, first time\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> postSchema\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> z.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">object\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  slug: z.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">min\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">).\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">max\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">80\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  title: z.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">min\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">).\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">max\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">160\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">});\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F server\u002Fdb\u002Fschema.ts — the shape, again\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> posts\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> sqliteTable\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'posts'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  slug: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'slug'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">).\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">notNull\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  title: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#032F62;--shiki-dark:#9ECBFF\">'title'\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">).\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">notNull\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">});\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F server\u002Fapi\u002Fposts.post.ts — wired by hand\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> body\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> postSchema.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">parse\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">await\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> readBody\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(event));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F app\u002Fcomponents\u002FPostForm.vue — the rules, again\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\"> rules\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> { title: [required, \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">maxLength\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">160\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">)] };\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F fronds\u002Fblog\u002Fentities\u002FPost.ts — the shape, once\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\">class\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> Post\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\"> entity\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  id: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">primary\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  slug: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({ min: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, max: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">80\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  title: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#6F42C1;--shiki-dark:#B392F0\">text\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">({ min: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">, max: \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">160\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">}) {}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Derived from it — nothing to keep in sync:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F   validation  (browser + façade, same judge)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F   SQLite table + additive schema sync\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F   form contract   useFormFor(Post)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F   API surface     post.create \u002F post.list\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F   GraphQL type    type Post { … }\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\"># Audit: how much schema glue does this repo maintain by hand?\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">You are auditing THIS repository. Be honest: report the costs\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">of switching as carefully as the gains.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">## Reference model — Fougere, a single-schema TS framework\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">One class declares a business object once:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">    class Post extends entity({\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      id: primary(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      slug: text({ min: 1, max: 80 }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      title: text({ min: 1, max: 160 }),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">      status: readOnly(oneOf('draft', 'published',\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">        { default: 'draft' })),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">    }) {}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Everything derives from it — input validation (the same judge\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">in the browser and at the API facade, unknown keys refused),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the SQL table (additive auto-DDL; renames, removals and type\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">changes need an explicit migration), the form contract (fields,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">rules, per-field error mapping), the API surface (post.list,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">post.create...), GraphQL types, and the TS type (the class IS\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the type). Business rules are handler operations, e.g.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">publish(id, user), judged server-side. Moving a module to its\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">own process is one line of config; user code does not change.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Scope today (pre-release): storage is additive auto-DDL over\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Kysely. SQLite resolves from its name; Postgres, MySQL and SQL\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Server work by handing Fougere the Kysely dialect you built\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">(setupKysely) — only you have the driver. No search-index\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">projection; auth via better-auth (credentials + OAuth). Price\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the adoption costs against THIS scope, not an imagined one.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">If you can fetch the web, ground yourself in the docs first:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> http:\u002F\u002Flocalhost\u002Fdocs — the model in one page\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> http:\u002F\u002Flocalhost\u002Fdocs\u002Fschema\u002Fentities — field vocabulary, the 4 axes\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> http:\u002F\u002Flocalhost\u002Fdocs\u002Fclient\u002Fforms — the shared browser\u002Ffacade judge\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> http:\u002F\u002Flocalhost\u002Fdocs\u002Fexisting-app — the feature-by-feature migration\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  path (use it to price the adoption cost honestly)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">## Measure, in this repo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">1.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> Identify the 3 most-touched business objects. A repo has\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   no traffic stats — use git churn as the proxy (most-modified\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   schema\u002Fform\u002Fhandler files over the last ~500 commits),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   crossed with the app's main forms and API routes.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">2.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> For each, list every file where its SHAPE is re-declared:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   validation schema (Zod\u002FYup\u002Fjoi), DB table or migration,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   API input\u002Foutput types, form state and rules, TS\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   interfaces, API-client types. Quote the paths. If one\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   object's shape belongs to an external system (legacy API,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   search index), audit it anyway and flag it: that is the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   unfavorable case, and it belongs in an honest report.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">3.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> Count the lines that exist ONLY to keep those in sync:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   parse\u002Fserialize, DTO mapping, hand-rolled error\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   formatting, manual refetch after mutations. Counting\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   rule: committed codegen output and pass-through wrappers\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   count; business logic in resolvers or computed fields\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   does not.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">4.\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> Look for one place where two of those declarations\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   already disagree (a max length, an optional, a nullable).\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   There usually is one — that drift is the argument. If there\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   is none here, say so plainly rather than reaching.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">## Report\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Per object: a table declaration-site → file → lines.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Then two totals, honestly:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> lines deletable under a derive-everything model;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#E36209;--shiki-dark:#FFAB70\">-\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> what adopting Fougere would cost HERE: storage handover\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  (SQLite auto-DDL today), pre-release status (not on npm\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  yet), the feature-by-feature migration path, what the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  team would have to learn.\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1786637818908]