Promote useMutation to the @probo/relay package

Extract the awaitable useMutation into @probo/relay as a
createUseMutation factory that delegates feedback to an injected
MutationNotifier, keeping the package free of UI and i18n
dependencies. compliance-portal binds it to its Base UI toast +
i18next + formatError stack and imports it by explicit path
(#/lib/relay/useMutation), dropping the lone intra-app barrel; a
compliance-portal-scoped no-restricted-imports rule forbids
react-relay's useMutation.

Bring packages/relay and packages/routes into the shared ESLint
scope and fix the violations that surfaced, and deprecate the
legacy withQueryRef / loaderFromQueryLoader helpers. Document the
shared-hook pattern and the "index.ts for package entrypoints only"
rule in the relay, hooks, and app-arborescence guides.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-24 10:28:57 +02:00
parent e93faf4caa
commit ff966b462e
14 changed files with 684 additions and 122 deletions

View File

@@ -5,7 +5,7 @@ import { defineConfig, globalIgnores } from "eslint/config";
// sets below; everything else is ignored so a bare `eslint .` keeps the same
// scope as the previous per-workspace configs.
const appDirs = ["apps/console/**", "apps/trust/**", "apps/compliance-portal/**"];
const reactDirs = [...appDirs, "packages/ui/**"];
const reactDirs = [...appDirs, "packages/ui/**", "packages/relay/**", "packages/routes/**"];
const lintedDirs = [...reactDirs, "packages/eslint-config/**"];
export default defineConfig([
@@ -25,8 +25,6 @@ export default defineConfig([
"packages/n8n-node/**",
"packages/prosemirror/**",
"packages/react-lazy/**",
"packages/relay/**",
"packages/routes/**",
"packages/tsconfig/**",
]),
{
@@ -48,6 +46,28 @@ export default defineConfig([
files: appDirs,
extends: [configs.relay],
},
{
// compliance-portal mutates through the awaitable useMutation bound in
// #/lib/relay/useMutation (over @probo/relay's createUseMutation), never
// react-relay's useMutation directly. Scoped to this app only: console and
// trust still use react-relay's useMutation.
files: ["apps/compliance-portal/**"],
rules: {
"no-restricted-imports": [
"error",
{
paths: [
{
name: "react-relay",
importNames: ["useMutation"],
message:
"Use useMutation from #/lib/relay/useMutation, not react-relay.",
},
],
},
],
},
},
{
files: reactDirs,
ignores: ["packages/ui/tailwind.config.js"],