prisma-php 0.0.2 → 0.0.4

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,24 @@
1
+ # Project Guidelines
2
+
3
+ ## Source Of Truth
4
+
5
+ - Treat `dist/docs/index.md` as the entry point for Prisma PHP guidance in this repo.
6
+ - Read the matching doc in `dist/docs` before generating or editing framework-specific Prisma PHP code.
7
+
8
+ ## Route File Conventions
9
+
10
+ - For PulsePoint-aware `index.php` and `layout.php`, keep file order as PHP, then HTML, then one `<script>` block.
11
+ - `index.php` and nested `layout.php` must render a single parent HTML element. Treat that root like a React-style component boundary rather than loose sibling markup.
12
+ - Only the root `layout.php` should define `<html>`, `<head>`, and `<body>`. When PulsePoint is present, keep `MainLayout::$children;` inside one clear wrapper.
13
+
14
+ ## Component Boundary Rules
15
+
16
+ - Distinguish PHPX class components from `ImportComponent` partials.
17
+ - `ImportComponent` partials must output exactly one root element because Prisma PHP attaches serialized props and a stable `pp-component` attribute to that root.
18
+ - Do not manually add `pp-component` unless a documented framework feature injects it for that boundary.
19
+
20
+ ## Relevant Docs
21
+
22
+ - Route and layout structure: `dist/docs/layouts-and-pages.md`
23
+ - PulsePoint runtime rules: `dist/docs/pulsepoint.md`
24
+ - Component and `ImportComponent` rules: `dist/docs/components.md`
@@ -193,6 +193,7 @@ The documented login flow uses:
193
193
  When generating credentials auth, do not trust raw request data.
194
194
 
195
195
  For backend validation and normalization, default to Prisma PHP’s validation layer rather than browser-only checks. In this docs set, that means using the documented validation guidance alongside `PP\Validator`-style server validation patterns from the rest of the local docs.
196
+ Read `validator.md` before generating credential validation, registration validation, or auth-related request normalization.
196
197
 
197
198
  ## Social authentication
198
199
 
@@ -69,6 +69,8 @@ This is the right mental model for:
69
69
  - componentized partials that PulsePoint should hydrate later
70
70
  - keeping PHP templating ergonomics while still producing component-aware markup
71
71
 
72
+ For `ImportComponent`, think in terms of a React-style single-root component: one parent element defines the island boundary, Prisma PHP serializes props onto that root, and the framework injects a stable `pp-component` attribute there. Do not design imported partials as loose sibling markup.
73
+
72
74
  AI must not collapse these two models into one.
73
75
 
74
76
  - **PHPX** is for class-based component authoring.
@@ -87,6 +89,8 @@ AI must not collapse these two models into one.
87
89
  - when a component needs reactivity, distinguish between static PHP props and reactive PulsePoint props
88
90
  - when a component requires grouped sub-components, follow the documented same-file naming pattern like `Accordion`, `AccordionItem`, `AccordionTrigger`, and `AccordionContent`
89
91
  - when using `ImportComponent`, always ensure the imported file renders **exactly one root element**
92
+ - treat the `ImportComponent` root as the real component boundary because Prisma PHP serializes props onto it and injects `pp-component`
93
+ - do not manually add `pp-component` inside imported partial source; let Prisma PHP inject it
90
94
 
91
95
  ## Component file placement and naming
92
96
 
@@ -253,6 +257,8 @@ Prisma PHP:
253
257
 
254
258
  - use `ImportComponent` for PHP partials, not for PHPX class components
255
259
  - require exactly one root element in the imported file
260
+ - keep the imported partial in Prisma PHP order: PHP preamble first, then one parent HTML element; if client script is needed, place the `<script>` inside that parent so the rendered output still has one root
261
+ - treat that single root as the component boundary that receives `pp-component` and serialized props
256
262
  - treat the imported output as a PulsePoint-ready island boundary
257
263
  - pass server data as props and let Prisma PHP serialize them into attributes
258
264
  - use mustache-valued props when passing reactive PulsePoint bindings into imported partials
@@ -309,20 +315,49 @@ use PP\ImportComponent;
309
315
 
310
316
  The imported PHP file must output **exactly one root element**.
311
317
 
318
+ That root is not just for layout or styling. It is the element Prisma PHP augments with `pp-component` and serialized props.
319
+
320
+ A leading PHP block for imports, variables, helpers, or `#[Exposed]` functions is valid. Root counting applies to the emitted top-level HTML/XML nodes only.
321
+
322
+ For imported Prisma PHP partials, keep the file in this shape:
323
+
324
+ 1. PHP
325
+ 2. one parent HTML element
326
+ 3. optional `<script>` inside that parent element
327
+
328
+ If the file emits a second top-level tag, including a sibling `<script>`, Prisma PHP will fail with an error such as `ImportComponent requires EXACTLY one root element. Found 2 root element(s)`.
329
+
312
330
  Correct:
313
331
 
314
332
  ```php
333
+ <?php
334
+
335
+ $title = 'Search';
336
+ ?>
337
+
315
338
  <div class="rounded-lg border bg-card p-4">
316
- <h2 class="font-medium">Search</h2>
339
+ <h2 class="font-medium"><?= $title ?></h2>
317
340
  <input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
341
+ <script type="text/pp">
342
+ console.log('Search component ready');
343
+ </script>
318
344
  </div>
319
345
  ```
320
346
 
321
347
  Incorrect:
322
348
 
323
349
  ```php
324
- <h2 class="font-medium">Search</h2>
325
- <input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
350
+ <?php
351
+
352
+ $title = 'Search';
353
+ ?>
354
+
355
+ <section class="rounded-lg border bg-card p-4">
356
+ <h2 class="font-medium"><?= $title ?></h2>
357
+ </section>
358
+ <script type="text/pp">
359
+ console.log('This script is a second root element');
360
+ </script>
326
361
  ```
327
362
 
328
363
  ## `ImportComponent` prop serialization rules
@@ -6,6 +6,7 @@ related:
6
6
  description: Learn more about the features mentioned on this page by reading the Prisma PHP docs.
7
7
  links:
8
8
  - /docs/error-handler
9
+ - /docs/php-validator
9
10
  - /docs/route-php
10
11
  - /docs/index-php
11
12
  - /docs/pages-and-layouts
@@ -62,6 +63,8 @@ In Prisma PHP, the recommended pattern is generally:
62
63
  - return a structured response or message
63
64
  - avoid letting routine validation failures become fatal exceptions
64
65
 
66
+ Read `validator.md` for the detailed local guidance on helper selection, rule syntax, and `Validator::withRules(...)` behavior.
67
+
65
68
  ### Form or direct function example
66
69
 
67
70
  ```php filename="src/app/contact/index.php"
@@ -6,6 +6,7 @@ related:
6
6
  description: Learn more about the features mentioned in this page by reading the Prisma PHP docs.
7
7
  links:
8
8
  - /docs/fetch-function
9
+ - /docs/php-validator
9
10
  - /docs/index-php
10
11
  - /docs/route-php
11
12
  - /docs/pages-and-layouts
@@ -18,6 +19,38 @@ Prisma PHP has a different mental model from Next.js. Instead of focusing on Rea
18
19
  When using `pp.fetchFunction(...)`, the PHP function must be explicitly exposed with `#[Exposed]`. Functions are private by default, so a non-exposed function cannot be called from the client.
19
20
 
20
21
  For validation, the default backend pattern should be **`PP\Validator`**. Use it to sanitize, cast, and validate values inside exposed functions and route handlers. This keeps the browser reactive while keeping the authoritative validation on the server.
22
+ Read `validator.md` alongside this page when you need the detailed helper list, rule syntax options, or the `Validator::withRules(...)` return contract.
23
+
24
+ ## Default AI decision rule
25
+
26
+ For **normal interactive full-stack Prisma PHP work**, AI should default to this stack:
27
+
28
+ 1. render the route with `index.php`
29
+ 2. use **PulsePoint** for browser-side state and reactive UI behavior
30
+ 3. use **`pp.fetchFunction(...)`** for frontend-to-PHP calls
31
+ 4. mark callable PHP functions with **`#[Exposed]`**
32
+ 5. use **`PP\Validator`** for authoritative backend validation and normalization
33
+
34
+ This should be the default for cases such as:
35
+
36
+ - live search
37
+ - filters
38
+ - pagination controls
39
+ - quick edit dialogs
40
+ - inline validation
41
+ - toggles and status changes
42
+ - modal-based mutations
43
+ - optimistic-feeling dashboard interactions
44
+ - route-local CRUD actions that belong to the current page
45
+
46
+ Do **not** default to a more PHP-only interaction style for those cases unless the **user explicitly asks for PHP-only behavior**.
47
+
48
+ A more PHP-only pattern is reasonable when:
49
+
50
+ - the user explicitly asks for plain PHP, classic form submission, or no PulsePoint
51
+ - the route is intentionally non-reactive
52
+ - the task is a standalone API, webhook, integration endpoint, or public JSON route
53
+ - the behavior must exist independently of the current page
21
54
 
22
55
  ## Validation is a server concern
23
56
 
@@ -49,6 +82,7 @@ For reactive UI work, the best Prisma PHP pattern is usually:
49
82
  4. return a structured object for the UI to render
50
83
 
51
84
  The official Validator docs recommend the **`Rule` builder** for most rule-based validation because it is easier to discover, easier to refactor, and less error-prone than raw pipe strings.
85
+ `validator.md` is the local source of truth for how this docs set expects AI to apply that guidance.
52
86
 
53
87
  ## Recommended pattern for reactive Prisma PHP UIs
54
88
 
@@ -59,9 +93,9 @@ For normal interactive UI work in Prisma PHP, the default approach should be:
59
93
  3. call PHP from the frontend with `pp.fetchFunction(...)`
60
94
  4. expose callable functions with `#[Exposed]`
61
95
 
62
- This is the preferred pattern for live search, inline validation, toggles, quick edits, filtering, lightweight mutations, and similar route-local interactions.
96
+ This is the preferred pattern for live search, inline validation, toggles, quick edits, filtering, lightweight mutations, pagination, modal workflows, and similar route-local interactions.
63
97
 
64
- Do **not** default to building extra `route.php` endpoints for every interactive action when `pp.fetchFunction(...)` is the better fit. Reserve `route.php` for explicit API-style endpoints, webhooks, JSON handlers, or routes that must be called independently of the page.
98
+ Do **not** default to building extra `route.php` endpoints for every interactive action when `pp.fetchFunction(...)` is the better fit. Also do **not** default to a PHP-only interaction model for normal reactive page behavior unless the user explicitly asks for that style. Reserve `route.php` for explicit API-style endpoints, webhooks, JSON handlers, or routes that must be called independently of the page.
65
99
 
66
100
  ## Fetching data in Prisma PHP
67
101
 
@@ -617,7 +651,7 @@ When fetching data from Prisma PHP:
617
651
  - every function called through `pp.fetchFunction(...)` must use `#[Exposed]`
618
652
  - return structured validation results instead of relying on thrown exceptions for routine failures
619
653
  - use `Exposed` options to enforce auth, roles, or rate limits
620
- - prefer `route.php` for dedicated public or integration-facing endpoints
654
+ - prefer `route.php` for dedicated public or integration-facing endpoints, not as the default answer for normal page-local interactivity
621
655
  - keep sensitive database access on the server side
622
656
 
623
657
  Because Prisma PHP runs the data logic in PHP, database credentials and internal query logic stay on the server.
@@ -634,4 +668,4 @@ Because Prisma PHP runs the data logic in PHP, database credentials and internal
634
668
  - `abortPrevious: true` helps cancel stale requests.
635
669
  - file uploads can be handled automatically without manual `FormData` in many cases.
636
670
  - `Exposed` can be used to declare authentication, allowed roles, and rate limits for callable functions.
637
- - for full-stack routes, load page data in `index.php` and use direct function invocation for interactive updates.
671
+ - for full-stack routes, load page data in `index.php` and use PulsePoint plus direct function invocation for interactive updates unless the user explicitly asks for a PHP-only flow.
@@ -15,6 +15,7 @@ related:
15
15
  Prisma PHP file handling should follow the documented **File Manager** model and standard PHP upload rules, not assumptions copied from Laravel storage disks, Symfony upload abstractions, Livewire temporary uploads, or custom Node-style multipart pipelines.
16
16
 
17
17
  If a task involves file uploads, upload forms, `$_FILES`, upload size limits, allowed file types, renaming, deleting, replacing files, or building a file manager UI, AI agents should read the relevant Prisma PHP File Manager docs first and keep the implementation aligned with the installed Prisma PHP version.
18
+ When the task also involves validating rename fields, labels, descriptions, or other non-file inputs, read `validator.md` alongside this page.
18
19
 
19
20
  ## AI rule: read the File Manager docs first
20
21
 
@@ -32,7 +33,7 @@ Do not assume another framework's storage abstraction applies directly.
32
33
  ## Read this doc when you need
33
34
 
34
35
  - **basic upload form setup, `multipart/form-data`, or raw `$_FILES` behavior** → official `get-started-file`
35
- - **upload validation and normalization for names or request values** → official `php-validator` plus local validation guidance in `fetching-data.md`, `error-handling.md`, and `route-handlers.md`
36
+ - **upload validation and normalization for names or request values** → `validator.md` first, then official `php-validator`, plus local validation guidance in `fetching-data.md`, `error-handling.md`, and `route-handlers.md`
36
37
  - **a rendered upload page or full-stack file manager screen** → `index.php` plus `layouts-and-pages.md`
37
38
  - **a standalone upload endpoint, webhook-like file receiver, or direct JSON upload handler** → `route.php` plus `route-handlers.md`
38
39
  - **local dev reload issues caused by uploaded files changing on disk** → inspect `./settings/bs-config.ts` and exclude the upload directory from BrowserSync tracking
@@ -210,6 +211,7 @@ For file manager pages and upload-related actions, keep these concerns separate:
210
211
  - use route pages or route handlers according to the documented `index.php` versus `route.php` split
211
212
 
212
213
  Do not use filename cleanup as a substitute for validating other request data.
214
+ For the full local validation contract, read `validator.md`.
213
215
 
214
216
  ## Organization guidance
215
217
 
@@ -277,7 +279,7 @@ When the user asks for upload or file-manager functionality, AI should usually f
277
279
  4. choose the upload destination directory
278
280
  5. if local reload becomes noisy, exclude the upload directory in `./settings/bs-config.ts`
279
281
  6. use `UploadFile` for upload, rename, update, and delete operations when it fits the documented workflow
280
- 7. use `PP\Validator` for rename fields or other non-file request values
282
+ 7. read `validator.md`, then use `PP\Validator` for rename fields or other non-file request values
281
283
  8. return structured messages for expected failures
282
284
  9. inspect Prisma PHP internals only if the docs and local project usage are not enough
283
285
 
@@ -8,7 +8,7 @@ related:
8
8
  - /docs/get-started
9
9
  ---
10
10
 
11
- {/_ AI agent hint: Prisma PHP uses local installed docs as the source of truth for the active project version. Before generating framework-specific code, read `prisma-php.json` first, then read the relevant docs from `node_modules/prisma-php/dist/docs`. For authentication, read `authentication.md` first, then verify the official auth docs: `auth-get-started`, `credentials`, and `state-manager-auth`. For file uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename/delete flows, or file manager screens, read `file-manager.md` first, then verify the official File Manager docs: `get-started-file`. For ORM work, read `prisma-php-orm.md` before choosing schema, migration, or generation commands. For PulsePoint runtime behavior specifically, read `pulsepoint.md` before generating reactive UI code. For backend validation, sanitization, `Validator`, `Rule`, `pp.fetchFunction(...)` validation flows, or request validation in `route.php`, read `fetching-data.md`, `error-handling.md`, and `route-handlers.md`, then consult the official Validator docs. `PP\Validator` is a Prisma PHP core class located in `vendor/tsnc/prisma-php/src/Validator.php`. Route creation is file-based from `src/app`; Prisma PHP auto-generates route listings such as `files-list.json`, so AI agents must not create, edit, or maintain that file manually. _/}
11
+ {/_AI agent hint: Prisma PHP uses local installed docs as the source of truth for the active project version. Before generating framework-specific code, read `prisma-php.json` first, then read the relevant docs from `node_modules/prisma-php/dist/docs`. For authentication, read `authentication.md` first, then verify the official auth docs: `auth-get-started`, `credentials`, and `state-manager-auth`. For file uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename/delete flows, or file manager screens, read `file-manager.md` first, then verify the official File Manager docs: `get-started-file`. For ORM work, read `prisma-php-orm.md` before choosing schema, migration, or generation commands. For PulsePoint runtime behavior specifically, read `pulsepoint.md` before generating reactive UI code. For normal interactive full-stack page work, default to PulsePoint plus `pp.fetchFunction(...)` unless the user explicitly asks for a PHP-only interaction style. When building PulsePoint-aware `index.php` or `layout.php`, keep PHP first, HTML second, and one `<script>` block last, with the rendered route content inside a single parent HTML element that acts as the route-view boundary. For imported partial components, keep exactly one root element because Prisma PHP uses that root as the component boundary where serialized props and `pp-component` attach. For backend validation, sanitization, `Validator`, `Rule`, `pp.fetchFunction(...)` validation flows, or request validation in `route.php`, read `validator.md` first, then use `fetching-data.md`, `error-handling.md`, and `route-handlers.md` for context-specific patterns, then consult the official Validator docs. `PP\Validator` is a Prisma PHP core class located in `vendor/tsnc/prisma-php/src/Validator.php`. Route creation is file-based from `src/app`; Prisma PHP auto-generates route listings such as `files-list.json`, so AI agents must not create, edit, or maintain that file manually._/}
12
12
 
13
13
  Welcome to the Prisma PHP documentation!
14
14
 
@@ -33,13 +33,26 @@ Use this order:
33
33
  3. Inspect local project files.
34
34
  4. Inspect `vendor/tsnc/prisma-php/src` only when framework internals are necessary.
35
35
 
36
+ ### Default interactive pattern
37
+
38
+ For typical full-stack Prisma PHP work, AI should assume this default:
39
+
40
+ 1. render route UI in `index.php`
41
+ 2. keep browser-side interactivity in **PulsePoint**
42
+ 3. call PHP from the frontend with **`pp.fetchFunction(...)`**
43
+ 4. expose callable functions with **`#[Exposed]`**
44
+ 5. validate and normalize incoming values in PHP with **`PP\Validator`**
45
+
46
+ Do **not** default to PHP-only interaction flows for normal reactive UI work unless the user explicitly asks for that style.
47
+
36
48
  ### Read this doc when you need
37
49
 
38
50
  - **project setup or file placement** → `project-structure.md`
39
- - **pages, layouts, route creation, nested routes** → `layouts-and-pages.md`
51
+ - **pages, layouts, route creation, nested routes, or PulsePoint-aware `index.php` and `layout.php` structure** → `layouts-and-pages.md`
40
52
  - **PHPX components, props, children, fragments, icons, buttons, accordions, or component composition** → `components.md`
41
53
  - **file uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename/delete flows, file replacement, allowed file types, upload size rules, or file manager pages** → `file-manager.md`
42
54
  - **authentication strategy, `AuthConfig.php`, sign-in, sign-out, route privacy model, RBAC, credentials auth, social login, or auth state manager usage** → `authentication.md`
55
+ - **validation, sanitization, casting, `PP\Validator`, `Rule`, or `Validator::withRules(...)`** → `validator.md`
43
56
  - **`pp.fetchFunction(...)`, `#[Exposed]`, page data loading, interactive validation with `Validator`** → `fetching-data.md`
44
57
  - **cache behavior and `CacheHandler`** → `caching.md`
45
58
  - **ORM, `schema.prisma`, database provider, migrations, generated PHP classes, `prisma.config.ts`, `.env` `DATABASE_URL`, or Prisma CLI workflow** → `prisma-php-orm.md`
@@ -57,7 +70,10 @@ Use this order:
57
70
  - do not guess routing, file conventions, request helpers, component APIs, reactive syntax, or auth behavior when local docs already define them
58
71
  - create routes by adding folders and route files under `src/app`
59
72
  - do not create, edit, or maintain `files-list.json`; Prisma PHP generates route listings automatically
60
- - when building interactive frontend behavior, prefer the documented PulsePoint pattern with browser-side reactive state and `pp.fetchFunction(...)` for server calls
73
+ - when building interactive frontend behavior, prefer the documented PulsePoint pattern with browser-side reactive state and `pp.fetchFunction(...)` for server calls; treat this as the default unless the user explicitly asks for a PHP-only interaction pattern
74
+ - when building PulsePoint inside `index.php` or `layout.php`, read `layouts-and-pages.md` together with `pulsepoint.md`, use PHP then HTML then one `<script>` block, keep route content inside a single parent HTML element, and treat that root as the route-view boundary
75
+ - when importing a PHP partial with `ImportComponent`, require exactly one root element because Prisma PHP attaches serialized props and a stable `pp-component` attribute to that root; do not manually sprinkle `pp-component` across normal route markup
76
+ - when building backend validation logic, read `validator.md` first, then use the route-specific docs for the request entry point
61
77
  - when using `pp.fetchFunction(...)`, expose the PHP function explicitly with `#[Exposed]`
62
78
  - when changing feature flags, update `prisma-php.json` first, then follow the documented update workflow
63
79
  - when building reusable PHPX components, read `components.md` first
@@ -78,7 +94,7 @@ Use `file-manager.md` as the local AI-awareness guide for:
78
94
  - choosing between a rendered upload page and a direct upload handler
79
95
  - validating non-file request values with `PP\Validator`
80
96
 
81
- After reading `file-manager.md`, verify the matching official docs at:
97
+ After reading `file-manager.md`, read `validator.md` when non-file request values are involved, then verify the matching official docs at:
82
98
 
83
99
  1. `get-started-file`
84
100
  2. `php-validator` when auxiliary request validation is needed
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  title: Layouts and Pages
3
- description: Learn how to create your first pages and layouts in Prisma PHP, and structure routes using the framework's file conventions.
3
+ description: Learn how to create your first pages and layouts in Prisma PHP, structure routes with the framework's file conventions, and keep PulsePoint-aware route files predictable.
4
4
  related:
5
5
  title: API Reference
6
- description: Learn more about the features mentioned in this page by reading the Prisma PHP routing documentation.
6
+ description: Learn more about the features mentioned in this page by reading the Prisma PHP routing and PulsePoint documentation.
7
7
  links:
8
8
  - /docs/pages-and-layouts
9
9
  - /docs/defining-routes
@@ -11,6 +11,7 @@ related:
11
11
  - /docs/private-folders
12
12
  - /docs/dynamic-route
13
13
  - /docs/index-php
14
+ - /docs/pulsepoint
14
15
  - /docs/route-php
15
16
  ---
16
17
 
@@ -28,7 +29,7 @@ When adding a page or nested route, create the correct folder and add the proper
28
29
 
29
30
  Prisma PHP has two important route entry files, and they serve different purposes.
30
31
 
31
- - `index.php` is the **UI entry point** for a route. Use it when the route should render HTML or a normal full-stack page.
32
+ - `index.php` is the **UI entry point** for a route. Use it when the route should render HTML or a normal full-stack page. In full-stack projects, this is also the default home for route-local PulsePoint-driven interactivity.
32
33
  - `route.php` is the **direct handler entry point** for a route. Use it when the route should behave like an API endpoint, JSON endpoint, AJAX handler, form-processing endpoint, or other no-view server handler.
33
34
 
34
35
  A helpful project-level rule comes from `prisma-php.json`:
@@ -44,7 +45,57 @@ For the example project configuration below, `backendOnly` is `false`, so the de
44
45
  }
45
46
  ```
46
47
 
47
- If the user asks for a **route or page**, prefer `index.php`. If the user asks for an **API route**, direct handler, JSON endpoint, webhook, or AJAX route, prefer `route.php`.
48
+ If the user asks for a **route or page**, prefer `index.php`. If the user asks for an **API route**, direct handler, JSON endpoint, webhook, or AJAX route, prefer `route.php`. Do not default to a PHP-only interaction style for normal page behavior when PulsePoint inside `index.php` is the better fit.
49
+
50
+ ## PulsePoint-aware file structure for `index.php` and `layout.php`
51
+
52
+ For normal interactive full-stack routes, the default Prisma PHP mental model should be:
53
+
54
+ 1. page UI in `index.php`
55
+ 2. browser-side state in PulsePoint
56
+ 3. route-local server calls through `pp.fetchFunction(...)`
57
+ 4. backend validation through `PP\Validator`
58
+
59
+ Only shift to a more PHP-only pattern when the user explicitly asks for it or when the route is intentionally non-reactive.
60
+
61
+ When `index.php` or `layout.php` includes PulsePoint, keep the file in this order:
62
+
63
+ 1. PHP
64
+ 2. HTML
65
+ 3. SCRIPT
66
+
67
+ In practice, that means:
68
+
69
+ - put imports, server-side queries, request access, helper functions, and exposed PHP functions in the top PHP block
70
+ - render the route markup after the PHP block
71
+ - place one PulsePoint `<script>` block at the bottom of the file
72
+
73
+ For the HTML portion, keep a **single parent HTML tag** around the route content, similar to React's single-root component rule. Treat that root as the page or layout boundary instead of as a throwaway wrapper.
74
+
75
+ - In `index.php`, wrap the page UI in one parent element such as `<main>`, `<section>`, or `<article>`, and treat that root as the route view's component-style boundary.
76
+ - In nested `layout.php`, wrap the shared layout UI and `<?= MainLayout::$children; ?>` in one parent element so the layout still behaves like one boundary.
77
+ - If that markup is later extracted into an `ImportComponent` partial, preserve the same single-root structure so Prisma PHP can attach the stable `pp-component` attribute to that root element.
78
+ - The root `layout.php` is the document shell and is the only layout that should contain `<html>` and `<body>`. Inside `<body>`, keep one clear wrapper around `<?= MainLayout::$children; ?>` when PulsePoint behavior is present.
79
+
80
+ Example PulsePoint page structure:
81
+
82
+ ```php filename="src/app/dashboard/index.php"
83
+ <?php
84
+
85
+ $title = 'Dashboard';
86
+ ?>
87
+ <section class="dashboard-page">
88
+ <h1><?= htmlspecialchars($title); ?></h1>
89
+ <p>Count: {count}</p>
90
+ <button onclick="setCount(count + 1)">Increment</button>
91
+ </section>
92
+
93
+ <script>
94
+ const [count, setCount] = pp.state(0);
95
+ </script>
96
+ ```
97
+
98
+ This order keeps server logic, rendered markup, and client reactivity easy to scan for both humans and AI tools.
48
99
 
49
100
  ## Creating a page
50
101
 
@@ -88,6 +139,7 @@ For example, to create a root layout:
88
139
  ```
89
140
 
90
141
  The root layout is defined at the top level of your app directory and wraps the content for the entire application.
142
+ If this root layout uses PulsePoint, keep the same file order: PHP first, then the document HTML, then a single `<script>` block near the end of `<body>`.
91
143
 
92
144
  ## Creating a nested route
93
145
 
@@ -159,6 +211,7 @@ src/app/
159
211
  ```
160
212
 
161
213
  If you combine both layouts, the root layout wraps the blog layout, and the blog layout wraps both `src/app/blog/index.php` and `src/app/blog/[slug]/index.php`.
214
+ Nested layouts should behave like single-root route views: one parent element should wrap the shared layout UI and `MainLayout::$children;`. Keep thinking in terms of one component-style boundary, not multiple sibling roots.
162
215
 
163
216
  ## Creating a dynamic segment
164
217
 
@@ -283,6 +336,8 @@ echo json_encode([
283
336
  - If a user asks for an API route or direct handler, prefer `route.php`.
284
337
  - The root layout is required and should contain the global HTML document structure.
285
338
  - Only the root layout should contain `<html>` and `<body>` tags.
339
+ - When `index.php` or `layout.php` uses PulsePoint, structure the file as PHP, then HTML, then one `<script>` block.
340
+ - `index.php` and nested `layout.php` should render one parent HTML element; only the root layout should contain `<html>` and `<body>`.
286
341
  - Layouts can be nested by placing `layout.php` files inside route folders.
287
342
  - Dynamic route parameters are available through `Request::$dynamicParams`.
288
343
  - Route groups let you organize routes and assign different layouts without affecting the URL.
@@ -39,6 +39,7 @@ vendor/tsnc/prisma-php/src/Validator.php
39
39
  ```
40
40
 
41
41
  `Validator` is the server-side validation layer for user input. It is not the ORM result layer.
42
+ For the full local validation contract, helper overview, and rule patterns, read `validator.md`.
42
43
 
43
44
  Use this split:
44
45
 
@@ -59,13 +59,22 @@ If an AI agent is working on the project, it should inspect `prisma-php.json` be
59
59
 
60
60
  One of the most important capability flags is `backendOnly`.
61
61
 
62
- - When `backendOnly` is `false`, the project is a **full-stack Prisma PHP app**. In that mode, normal route UI should be implemented with `index.php`.
62
+ - When `backendOnly` is `false`, the project is a **full-stack Prisma PHP app**. In that mode, normal route UI should be implemented with `index.php`, and interactive page behavior should usually be implemented with PulsePoint plus `pp.fetchFunction(...)`.
63
63
  - When `backendOnly` is `true`, the project is a **backend-only Prisma PHP app**. In that mode, route behavior will usually center on direct handlers such as `route.php`.
64
- - If a `route.php` file exists at a route segment, it acts as the direct handler entry point for that route and should be treated as the API-style or no-view path for that segment.
64
+ - If a `route.php` file exists at a route segment, it acts as the direct handler entry point for that route and should be treated as the API-style or no-view path for that segment, not as the default destination for ordinary route-local interactivity.
65
65
  - In full-stack projects, if the user asks for a normal route or page, prefer `index.php`. If the user asks for an API route, JSON endpoint, form-processing endpoint, AJAX endpoint, or direct handler, prefer `route.php`.
66
66
 
67
67
  This helps AI and contributors choose the correct file without guessing based on other frameworks.
68
68
 
69
+ For AI-assisted generation, the default full-stack route pattern should be:
70
+
71
+ 1. render page UI in `index.php`
72
+ 2. keep browser interactivity in PulsePoint
73
+ 3. use `pp.fetchFunction(...)` for frontend-to-PHP calls that belong to the page
74
+ 4. use `route.php` only when the behavior must exist as a standalone handler or API-style endpoint
75
+
76
+ Only prefer a more PHP-only interaction pattern when the user explicitly asks for it.
77
+
69
78
  ### Framework-managed generated files
70
79
 
71
80
  Some files in a Prisma PHP project are framework-managed and should not be manually maintained as part of normal route work.