[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"cw:fronds\u002Fblog\u002Fentities\u002FPost.ts — and what derives":3,"cw:fronds\u002Fblog\u002Fentities\u002FPost.ts":4,"cw:fronds\u002Fblog\u002Fhandlers\u002FPostHandler.ts":5,"cw:app\u002Fpages\u002Fblog\u002Findex.vue":6,"cw:demos\u002Frust-frond — the TS consumer's output":7,"cw:your-nuxt-app\u002F — 4 files":8,"cw:your-fougere-app\u002F — 1 file":3,"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:#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 validator)\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:#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\">.storage.\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\"> '@fronds\u002Ffacade'\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 that facade 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:#005CC5;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\"># Audit: what does the NEXT business object cost here?\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 of\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">adopting as carefully as the gains, and what would get WORSE as\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">carefully as what improves. Nothing below asks you to price a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">rewrite — Fougere is added beside what exists, one object at a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">time, and the question is what the next one costs.\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 validator\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), validated 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, and\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">one optional package puts a span on every operation.\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\">(createKyselySource) — 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, though an external source is mirrored into entities\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">you declare; auth via better-auth (credentials + OAuth), or the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">sessions you already have behind an auth provider whose\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">getSession reads them. Price the adoption costs against THIS\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">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\"> https:\u002F\u002Ffougere.dev\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\"> https:\u002F\u002Ffougere.dev\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\"> https:\u002F\u002Ffougere.dev\u002Fdocs\u002Fclient\u002Fforms — the shared browser\u002Ffacade validator\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\"> https:\u002F\u002Ffougere.dev\u002Fdocs\u002Finfra\u002Fgradient — the process boundary as config\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\"> https:\u002F\u002Ffougere.dev\u002Fdocs\u002Finfra\u002Fobservability — the span nobody writes\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\"> https:\u002F\u002Ffougere.dev\u002Fdocs\u002Fexisting-app — the feature-by-feature path\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  (use it to price the adoption cost 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\"> https:\u002F\u002Ffougere.dev\u002Fdocs\u002Fdemos — whole projects, if you want the shape\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  of a finished one\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:#24292E;--shiki-dark:#E1E4E8\">Every section asks the same question about a different subject:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">for one thing Fougere DERIVES, how many lines does this repo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">write by hand? A declaration should name nothing outside itself —\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">not a table, not a protocol, not a host, not an address — and\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">nothing should have to be written twice per operation.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Measure. Quote real paths and numbers you counted. Where a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">section finds nothing, say \"nothing\" — that is a result.\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\">### 1. What the next object costs\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Do NOT start from the most-touched objects. Churn selects the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">most MATURE ones — most business logic, highest migration cost,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">least reason to move. That is the unfavourable case and nobody\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">buys it. Start from what was added recently.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">A business object is something a person creates or edits: it has\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">a form, or a public API route. A join table, a job queue, a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">session or an idempotency key is not one. Say which you excluded.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">a. Find the business objects added in the last ~12 months.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">   `git log --diff-filter=A`\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> over migration files works only if\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   this repo HAS per-change migration files. If it does not (a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">   `db push`\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> workflow, one schema file per domain, a single\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   models.py), search the diffs instead:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">   `git log -p --since=1.year -- &#x3C;schema paths> | grep '^+model\\|^+class\\|^+CREATE TABLE'`\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   For each, count the files its introduction touched.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">b. Do the same for commits that add ONE field.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">c. Report the MEDIAN of each, over at least five commits, not a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   single example — one commit is noise. Say how many you used.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">d. Say how OFTEN this happens: new objects per year, new fields\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   per year. A high per-object cost paid twice a year is a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   different argument from one paid every week, and the honest\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">   report says which this is.\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\">### 2. What a rename costs\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Find a commit that renamed a business object or one of its\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">fields, and count the files it touched. If there is none, take\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the object from 1a and count the files that would have to change\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">to rename one field.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">This is the number a single declaration changes most, and it is\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">usually the largest one in the repo.\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\">### 3. Where the shape is re-declared\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Take the object from 1a and the one or two the app is most built\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">around. List every file where their 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, API\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">input\u002Foutput types, form state and rules, TS interfaces,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">API-client types. Quote the paths.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Two traps worth naming:\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\"> an object's shape may be FED by an external system (legacy\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  API, search index). You still declare the shape and everything\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  derives; a Mirror writes pages into it. Only the translation of\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  the foreign payload stays. Count the two separately.\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\"> a constraint can disagree with a default nobody typed — a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">  `.max(255)`\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> against a column that is \u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#005CC5;--shiki-dark:#79B8FF\">`VARCHAR(191)`\u003C\u002Fspan>\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\"> because\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  the ORM defaults there. Check the defaults, not just what is\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  written.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\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 formatting,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">manual refetch after mutations. Counting rule: committed codegen\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">output and pass-through wrappers count; business logic in\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">resolvers or computed fields does not.\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\">### 4. Where the code names a place\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Count the files of BUSINESS code — not config, not the HTTP\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">layer itself — that name where they run:\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\"> base URLs or per-service env vars read outside one config file\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\"> hand-written fetch\u002Faxios wrappers, one per service called\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\"> imports of request\u002Fresponse types, or of any host-specific\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  context object, inside domain code\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\"> anything that would have to change to run on another runtime\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  (Node, edge, a worker)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Report that file count. It is the answer whether or not this\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">repo is one process or intends to stay one — a single process\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">that names its host in domain code has the same coupling, it\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">just has not paid for it yet.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Then, if the repo is or wants to be more than one process: pick\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the module you would most plausibly split, say where you drew\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">its boundary, and count the files that would change. Fougere's\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">answer is one config line with user code untouched.\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\">### 5. What you write around every operation\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Fougere derives a span per operation, the four signals, and test\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">cases from the entity. Count what this repo writes by hand for\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the same result:\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\"> lines that start or annotate a span, time a block, or log\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  entry\u002Fexit around business calls\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\"> how a request ID or trace context is carried between two\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  services, and how many files carry it\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\"> test fixtures that restate an object's shape — a factory, a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  builder, a JSON sample per test\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">If this repo has no tracing and does not want any, say so.\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\">### 6. The drift\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Find where two declarations of the same thing already disagree —\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">a max length, an optional, a nullable, an enum with an extra\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">value. Sweep rather than hunt: a short script comparing declared\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">lengths on both sides usually finds a family at once. Report\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">every family you find, quote the two declarations, and say what\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">breaks in the gap between them. If there is none, say so plainly\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">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\">Lead with the rule that selected the objects you audited and\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">the ones it rejected. Then four numbers: files per new object,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">files per new field, files per rename, files of business code\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">that name a host. Then the drift from 6, quoted, with what breaks.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">Then, 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\"> what those numbers become under a derive-everything model, and\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  how many of the lines from 3 and 5 stop existing;\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 this repo ALREADY derives — generated clients, inferred\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  types, a shared validator. Those lines are not a gain, and a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  report that counts them is lying;\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 would get WORSE. Name the database features in use that\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  Fougere's scope does not cover today, and anything it would\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  make harder. An audit that finds no downside has not looked;\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 would cost HERE, in the units the gains use. A\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  cost is a count of files, a named mechanism, or a version —\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  never a grade. An object added beside what exists needs no\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  table handover, so name instead what a second writer in this\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  database means for the migration tool already installed, the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  pre-release status (npm alpha tag, APIs still settling), the\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  feature-by-feature path, and what the team must learn. Price a\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  handover only for an object you propose to MOVE, and say why\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  it has to move;\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\"> where the FIRST entity would go. Name the next object this team\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  is about to write — a branch in progress, a table nobody reads\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  yet — not the biggest one they already have. If nothing is\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-default:#24292E;--shiki-dark:#E1E4E8\">  coming, say that: it is the real answer.\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1790930236062]