@vertesia/appgen-docs 1.5.0-dev.20260910.052912Z → 1.6.0-dev.20260912.110338Z

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ # Current-project Interactions Recipe
2
+
3
+ This recipe is generated with the installed `@vertesia/client` and `@vertesia/common` versions. Use it instead
4
+ of searching dependency source for the browser client signature.
5
+
6
+ ## List interactions from React
7
+
8
+ ```tsx
9
+ import type { InteractionRef } from '@vertesia/common';
10
+ import { useFetch } from '@vertesia/ui/core';
11
+ import { useUserSession } from '@vertesia/ui/session';
12
+
13
+ export function InteractionCatalog() {
14
+ const { client } = useUserSession();
15
+ const { data = [] } = useFetch<InteractionRef[]>(() => client.interactions.list(), {
16
+ deps: [client],
17
+ defaultValue: [],
18
+ });
19
+
20
+ return <ul>{data.map((interaction) => <li key={interaction.id}>{interaction.name}</li>)}</ul>;
21
+ }
22
+ ```
23
+
24
+ ## Stable signatures
25
+
26
+ - `client.interactions.list(payload?: InteractionSearchPayload): Promise<InteractionRef[]>`.
27
+ - Empty input is valid. Use `client.interactions.list()` unless the task requires a server-side filter.
28
+ - The useful `InteractionRef` fields are `id`, `name`, `endpoint`, `description?`, `status`, `version`,
29
+ `tags`, and `updated_at`.
30
+ - `InteractionRef` deliberately has no `type` field. When a current-project catalog must display type, call
31
+ `client.interactions.catalog.listStoredInteractions()`, which returns `Promise<CatalogInteractionRef[]>`; do not
32
+ search generated declarations for `InteractionRef.type` or infer it from another field.
33
+ - `listStoredInteractions()` sends `GET /api/v1/interactions/catalog/stored` (plus optional `status` or `tag`
34
+ query parameters). Its JSON response is the bare `CatalogInteractionRef[]` array, never an `{ items: [...] }`
35
+ wrapper. A focused Playwright mock can route `**/api/v1/interactions/catalog/stored**` and fulfill that bare array.
36
+ - The useful `CatalogInteractionRef` fields are `type` (`'stored'` for this endpoint), `id`, `name`, `title`,
37
+ `description?`, `version?`, and `tags`. Use `client.interactions.catalog.list()` only when the task explicitly
38
+ asks for the combined system, app, and stored catalog rather than the current project's stored interactions.
39
+ - This recipe fully specifies the method, return type, endpoint, and response shape. Do not probe the live API, inspect
40
+ `node_modules`, or call `app_docs_grep`/`app_docs_read` to reconfirm them. Treat a concrete workspace typecheck or
41
+ Playwright failure as the only reason to inspect one exact symbol afterward.
42
+ - Keep SDK methods attached to their topic: call `client.interactions.list()`; do not destructure `list`.
43
+ - The session client is already scoped to the signed-in user's current project. Do not construct another client in
44
+ browser code and do not hardcode a project id.
45
+ - For schemas, use `client.interactions.export({})`; for the normal catalog, use `list()`.
@@ -0,0 +1,92 @@
1
+ # UI Components Recipe
2
+
3
+ This recipe is generated with the installed `@vertesia/ui` version. Use it for common app screens instead of
4
+ searching dependency source. For an API not covered here, search `appgen/ui-interfaces.d.ts` once by exact symbol.
5
+
6
+ For a current-project interaction catalog built with the table, button, and fetch APIs below, this recipe is complete.
7
+ After reading it, do not search generated declarations or dependency source for `Table`, `TBody`, `useFetch`, or
8
+ the interaction catalog merely to reconfirm these signatures. Implement the screen and let the first workspace typecheck
9
+ identify any real version drift; only then search once for the exact symbol named by that diagnostic.
10
+
11
+ ## Imports
12
+
13
+ ```tsx
14
+ import {
15
+ Button,
16
+ Table,
17
+ TableHeaderCell,
18
+ TBody,
19
+ THead,
20
+ TR,
21
+ useFetch,
22
+ } from '@vertesia/ui/core';
23
+ ```
24
+
25
+ These are runtime React values, not types. Import `Table`, `TBody`, `THead`, `TR`, `TableHeaderCell`, `Button`,
26
+ and `useFetch` with a normal `import`; using `import type` makes JSX fail with TS1361.
27
+
28
+ ## Loading table with refresh
29
+
30
+ `TBody.columns` is required. It is the number of rendered columns and drives the loading skeleton.
31
+ Use `TableHeaderCell` instead of raw `<th>` so column scope is accessible by default.
32
+
33
+ ```tsx
34
+ const { data = [], error, isLoading, refetch } = useFetch(loadRows, { deps: [projectId], defaultValue: [] });
35
+
36
+ <Button type="button" onClick={() => void refetch()} isLoading={isLoading}>
37
+ Refresh
38
+ </Button>
39
+
40
+ {error ? <p role="alert">{error.message}</p> : null}
41
+ <Table>
42
+ <THead>
43
+ <TR>
44
+ <TableHeaderCell>Name</TableHeaderCell>
45
+ <TableHeaderCell>Status</TableHeaderCell>
46
+ </TR>
47
+ </THead>
48
+ <TBody columns={2} isLoading={isLoading}>
49
+ {data.map((row) => (
50
+ <TR key={row.id}>
51
+ <td>{row.name}</td>
52
+ <td>{row.status}</td>
53
+ </TR>
54
+ ))}
55
+ </TBody>
56
+ </Table>
57
+ {!isLoading && !error && data.length === 0 ? <p>No results found.</p> : null}
58
+ ```
59
+
60
+ ## Stable signatures
61
+
62
+ - `useFetch<T>(fetcher, { deps, defaultValue, onSuccess, onError })` returns
63
+ `{ data, isLoading, error, setData, refetch }`.
64
+ - `TBody` accepts `{ columns: number; isLoading?: boolean; rows?: number; children: ReactNode }`.
65
+ - `Button` accepts normal button props plus `isLoading`, `isDisabled`, `variant`, and `size`.
66
+ - Icon-only buttons need `aria-label`. Text buttons should keep their visible text in the accessible name.
67
+ - Use a native `<section aria-label="…">` for a labeled table/overflow region. Do not put `role="region"` on a
68
+ `<div>`; Biome's `lint/a11y/useSemanticElements` requires the semantic element.
69
+ - Prefer semantic theme classes and plain HTML for layout. Do not guess private `@vertesia/ui` paths.
70
+
71
+ ## Generated app tests
72
+
73
+ - The standard generated app runs Vitest in a Node environment and intentionally does not install jsdom,
74
+ happy-dom, or Testing Library. Do not search dependency trees or add a DOM-test dependency for a UI-only change.
75
+ - Put loading/error/empty/populated/refresh decisions in a separate production `*.state.ts` or `*.model.ts` module
76
+ imported and used by the component. Cover that state matrix by importing the pure module directly from the focused unit
77
+ test. Do not export the helper only from the component's TSX module: importing that file also loads the real
78
+ `@vertesia/ui` runtime, which the standard Node-only Vitest environment cannot execute. Do not copy the helper into
79
+ the test or walk rendered React element internals; the tested module must remain on the production import path.
80
+ - Source Playwright specs import `type { Page }` from `@playwright/test` and `{ expect, test }` from
81
+ `./vertesia`. Type shared helpers as `page: Page`; never hand-write a structural Page or Route type because
82
+ Playwright's overloaded callbacks will reject narrower substitutes. Use `page.route` to mock only the real API
83
+ path involved in the primary flow (interaction listing uses a path containing `/interactions`), then exercise the
84
+ page through accessible roles. Use the declared `test:e2e` script and its `PLAYWRIGHT_BASE_URL`; do not invent a
85
+ second browser harness.
86
+ - Scope repeated text to its semantic container and request an exact accessible name. For example, use
87
+ `table.getByRole('cell', { name: interactionName, exact: true })` when the same name can also occur in tags or
88
+ descriptions; an unscoped text or name locator can match several elements and waste a browser retry.
89
+ - For a responsive table, prove document-level overflow is absent and intentional overflow stays on one labeled table
90
+ region. Assert positive horizontal overflow only at the narrow viewport—a desktop table may fit—and scroll that region
91
+ before using `toBeInViewport()` on the final required column. DOM presence or `toBeVisible()` alone does not prove an
92
+ off-screen mobile column is reachable.