caspian-utils 0.1.12 → 0.1.13
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.
- package/dist/docs/commands.md +26 -26
- package/dist/docs/database.md +62 -62
- package/dist/docs/pulsepoint-runtime-map.md +1 -0
- package/dist/docs/pulsepoint.md +19 -11
- package/package.json +1 -1
package/dist/docs/commands.md
CHANGED
|
@@ -103,17 +103,17 @@ Do not use `npm run build` as the default validation step for routine route, fea
|
|
|
103
103
|
```bash
|
|
104
104
|
npx prisma migrate dev
|
|
105
105
|
|
|
106
|
-
# If the change requires refreshed seed data:
|
|
107
|
-
npx prisma generate
|
|
108
|
-
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
109
|
-
npx prisma db seed
|
|
110
|
-
|
|
111
|
-
npx ppy generate
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
|
|
115
|
-
|
|
116
|
-
`npx prisma db seed` is a delicate operation because the configured seed script may clean tables or replace existing rows before inserting seed data. Before running it, an AI agent must say the exact command it plans to run, warn that it can delete or overwrite database data, confirm the active datasource when practical, and wait for explicit user approval.
|
|
106
|
+
# If the change requires refreshed seed data:
|
|
107
|
+
npx prisma generate
|
|
108
|
+
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
109
|
+
npx prisma db seed
|
|
110
|
+
|
|
111
|
+
npx ppy generate
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
|
|
115
|
+
|
|
116
|
+
`npx prisma db seed` is a delicate operation because the configured seed script may clean tables or replace existing rows before inserting seed data. Before running it, an AI agent must say the exact command it plans to run, warn that it can delete or overwrite database data, confirm the active datasource when practical, and wait for explicit user approval.
|
|
117
117
|
|
|
118
118
|
## 2. Script Guardrails
|
|
119
119
|
|
|
@@ -182,12 +182,12 @@ In skip-prompt mode, the default feature values are:
|
|
|
182
182
|
|
|
183
183
|
- `backendOnly: false`
|
|
184
184
|
- `tailwindcss: false`
|
|
185
|
-
- `typescript: false`
|
|
186
|
-
- `mcp: false`
|
|
187
|
-
- `prisma: false`
|
|
188
|
-
- `websocket: false`
|
|
189
|
-
|
|
190
|
-
If a project needs WebSockets after creation, set `websocket: true` in `caspian.config.json`, then run the project update workflow so framework-managed files and any scaffolded socket surfaces stay aligned before assuming `@app.websocket(...)` routes or `src/lib/websocket/**` exist.
|
|
185
|
+
- `typescript: false`
|
|
186
|
+
- `mcp: false`
|
|
187
|
+
- `prisma: false`
|
|
188
|
+
- `websocket: false`
|
|
189
|
+
|
|
190
|
+
If a project needs WebSockets after creation, set `websocket: true` in `caspian.config.json`, then run the project update workflow so framework-managed files and any scaffolded socket surfaces stay aligned before assuming `@app.websocket(...)` routes or `src/lib/websocket/**` exist.
|
|
191
191
|
|
|
192
192
|
### 4.2 Backend-only combinations
|
|
193
193
|
|
|
@@ -598,18 +598,18 @@ The create and update commands above are not the whole maintenance story for a P
|
|
|
598
598
|
```bash
|
|
599
599
|
npx prisma migrate dev
|
|
600
600
|
|
|
601
|
-
# Only when seed flow or prisma/seed.ts depends on the new schema:
|
|
602
|
-
npx prisma generate
|
|
603
|
-
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
604
|
-
npx prisma db seed
|
|
605
|
-
|
|
606
|
-
npx ppy generate
|
|
607
|
-
```
|
|
601
|
+
# Only when seed flow or prisma/seed.ts depends on the new schema:
|
|
602
|
+
npx prisma generate
|
|
603
|
+
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
604
|
+
npx prisma db seed
|
|
605
|
+
|
|
606
|
+
npx ppy generate
|
|
607
|
+
```
|
|
608
608
|
|
|
609
609
|
Use this order:
|
|
610
610
|
|
|
611
611
|
1. Run `npx prisma migrate dev` first so migrations and the development database stay aligned.
|
|
612
|
-
2. If `prisma/seed.ts` or seed data depends on the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed` because the seed script may delete or overwrite database data.
|
|
612
|
+
2. If `prisma/seed.ts` or seed data depends on the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed` because the seed script may delete or overwrite database data.
|
|
613
613
|
3. Run `npx ppy generate` last so the generated Python ORM layer matches the updated Prisma schema.
|
|
614
614
|
|
|
615
615
|
Do not manually create or edit these generated files:
|
|
@@ -682,7 +682,7 @@ If an AI agent is deciding which command flow to use, apply these rules first.
|
|
|
682
682
|
- Treat `--tailwindcss` and `--typescript` as frontend-oriented flags. They are not meaningful in normal backend-only scaffolds.
|
|
683
683
|
- Treat starter kit defaults as a base layer that can be overridden by explicit flags.
|
|
684
684
|
- Read `caspian.config.json` before running update commands.
|
|
685
|
-
- When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first, then any required seed refresh, then `npx ppy generate`. Before running `npx prisma db seed`, warn the user that it can delete or overwrite data and wait for explicit approval.
|
|
685
|
+
- When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first, then any required seed refresh, then `npx ppy generate`. Before running `npx prisma db seed`, warn the user that it can delete or overwrite data and wait for explicit approval.
|
|
686
686
|
- Never hand-edit generated Python ORM files under `src/lib/prisma/` or `settings/prisma-schema.json`.
|
|
687
687
|
- Read [database.md](./database.md) before generating Prisma schema, migration, seed, or ORM guidance.
|
|
688
688
|
- Read [routing.md](./routing.md) before generating or modifying route folders under `src/app/`.
|
package/dist/docs/database.md
CHANGED
|
@@ -14,38 +14,38 @@ related:
|
|
|
14
14
|
|
|
15
15
|
This page documents the Prisma workflow for Caspian projects where `caspian.config.json` enables Prisma.
|
|
16
16
|
|
|
17
|
-
When a project enables Prisma, use `prisma/schema.prisma` for schema management, `prisma.config.ts` for Prisma config and seed wiring, and reuse an app-owned `src/lib/prisma/` package when the project includes one.
|
|
18
|
-
|
|
19
|
-
High-priority rule: when `caspian.config.json` has `prisma: true`, Python-side database access must use the generated Prisma Python ORM. Route `page()` functions, route-owned `@rpc()` actions, auth handlers, upload flows, and shared helpers should import the generated client from `src/lib/prisma/**` instead of inventing direct driver calls, hand-written SQL wrappers, JSON manifests as active stores, app-specific HTTP fetches, or browser-side database fetches. For normal reads and writes, default to Prisma methods such as `find_many`, `find_unique`, `create`, `update`, `delete`, `delete_many`, aggregates, includes, and transactions. Use raw SQL only through Prisma as a narrow fallback when the generated ORM cannot express a query clearly, and treat that fallback as provider-specific code that may break when a project moves between SQLite, MySQL, and PostgreSQL.
|
|
17
|
+
When a project enables Prisma, use `prisma/schema.prisma` for schema management, `prisma.config.ts` for Prisma config and seed wiring, and reuse an app-owned `src/lib/prisma/` package when the project includes one.
|
|
18
|
+
|
|
19
|
+
High-priority rule: when `caspian.config.json` has `prisma: true`, Python-side database access must use the generated Prisma Python ORM. Route `page()` functions, route-owned `@rpc()` actions, auth handlers, upload flows, and shared helpers should import the generated client from `src/lib/prisma/**` instead of inventing direct driver calls, hand-written SQL wrappers, JSON manifests as active stores, app-specific HTTP fetches, or browser-side database fetches. For normal reads and writes, default to Prisma methods such as `find_many`, `find_unique`, `create`, `update`, `delete`, `delete_many`, aggregates, includes, and transactions. Use raw SQL only through Prisma as a narrow fallback when the generated ORM cannot express a query clearly, and treat that fallback as provider-specific code that may break when a project moves between SQLite, MySQL, and PostgreSQL.
|
|
20
20
|
|
|
21
21
|
Treat `caspian.config.json` as the single source of truth for whether Prisma is enabled in a workspace. If `prisma` is false and the user wants Prisma, ask first, then update `caspian.config.json` and run `npx casp update project` before assuming Prisma-managed files exist.
|
|
22
22
|
|
|
23
23
|
## Overview
|
|
24
24
|
|
|
25
|
-
The standard Prisma flow in Caspian is:
|
|
26
|
-
|
|
27
|
-
1. Define models in `prisma/schema.prisma`.
|
|
28
|
-
2. Configure `DATABASE_URL` in `.env`.
|
|
29
|
-
3. Run `npx prisma migrate dev` after schema changes so the development database and migration history stay aligned.
|
|
30
|
-
4. If the change requires seed data, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
31
|
-
5. Run `npx ppy generate` so the Python ORM classes stay aligned with the updated schema.
|
|
32
|
-
6. Reuse the shared Python database layer in `src/lib/prisma/` when Python route or RPC code needs database access, and never hand-edit generated ORM classes.
|
|
33
|
-
|
|
34
|
-
Use this workflow instead of writing raw SQL first. For normal CRUD and relation work, stay on the generated Prisma API. Drop to raw SQL only through Prisma when a query cannot be expressed clearly with the generated client, and assume that raw SQL requires extra review for cross-database portability.
|
|
35
|
-
|
|
36
|
-
## Seed Command Safety
|
|
37
|
-
|
|
38
|
-
Treat `npx prisma db seed` as a destructive data operation, not as a routine regeneration command. A project's `prisma/seed.ts` may delete existing rows, reset lookup tables, replace users, or otherwise rewrite the current datasource before inserting seed data. If `DATABASE_URL` points at a shared, staging, or production database, running the seed command can delete production information.
|
|
39
|
-
|
|
40
|
-
Before any AI agent runs `npx prisma db seed`, it must:
|
|
41
|
-
|
|
42
|
-
1. Read `prisma.config.ts` and `prisma/seed.ts` to understand what the seed command will execute.
|
|
43
|
-
2. State the exact command it intends to run: `npx prisma db seed`.
|
|
44
|
-
3. Warn the user clearly that the command can delete or overwrite database data.
|
|
45
|
-
4. Confirm the active datasource or `DATABASE_URL` when practical, without exposing secrets.
|
|
46
|
-
5. Wait for explicit user approval before executing the command.
|
|
47
|
-
|
|
48
|
-
Do not run `npx prisma db seed` merely because it appears in the standard workflow. Ask first, and only continue after the user has approved that specific seed operation.
|
|
25
|
+
The standard Prisma flow in Caspian is:
|
|
26
|
+
|
|
27
|
+
1. Define models in `prisma/schema.prisma`.
|
|
28
|
+
2. Configure `DATABASE_URL` in `.env`.
|
|
29
|
+
3. Run `npx prisma migrate dev` after schema changes so the development database and migration history stay aligned.
|
|
30
|
+
4. If the change requires seed data, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
31
|
+
5. Run `npx ppy generate` so the Python ORM classes stay aligned with the updated schema.
|
|
32
|
+
6. Reuse the shared Python database layer in `src/lib/prisma/` when Python route or RPC code needs database access, and never hand-edit generated ORM classes.
|
|
33
|
+
|
|
34
|
+
Use this workflow instead of writing raw SQL first. For normal CRUD and relation work, stay on the generated Prisma API. Drop to raw SQL only through Prisma when a query cannot be expressed clearly with the generated client, and assume that raw SQL requires extra review for cross-database portability.
|
|
35
|
+
|
|
36
|
+
## Seed Command Safety
|
|
37
|
+
|
|
38
|
+
Treat `npx prisma db seed` as a destructive data operation, not as a routine regeneration command. A project's `prisma/seed.ts` may delete existing rows, reset lookup tables, replace users, or otherwise rewrite the current datasource before inserting seed data. If `DATABASE_URL` points at a shared, staging, or production database, running the seed command can delete production information.
|
|
39
|
+
|
|
40
|
+
Before any AI agent runs `npx prisma db seed`, it must:
|
|
41
|
+
|
|
42
|
+
1. Read `prisma.config.ts` and `prisma/seed.ts` to understand what the seed command will execute.
|
|
43
|
+
2. State the exact command it intends to run: `npx prisma db seed`.
|
|
44
|
+
3. Warn the user clearly that the command can delete or overwrite database data.
|
|
45
|
+
4. Confirm the active datasource or `DATABASE_URL` when practical, without exposing secrets.
|
|
46
|
+
5. Wait for explicit user approval before executing the command.
|
|
47
|
+
|
|
48
|
+
Do not run `npx prisma db seed` merely because it appears in the standard workflow. Ask first, and only continue after the user has approved that specific seed operation.
|
|
49
49
|
|
|
50
50
|
## Environment Setup
|
|
51
51
|
|
|
@@ -63,7 +63,7 @@ Example for PostgreSQL in async-friendly production environments:
|
|
|
63
63
|
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
For most local development, SQLite is the simplest starting point. For production or higher concurrency workloads, prefer PostgreSQL or MySQL. Regardless of the starting provider, keep application queries on the Prisma ORM whenever possible so schema and query behavior stay easier to migrate across providers.
|
|
66
|
+
For most local development, SQLite is the simplest starting point. For production or higher concurrency workloads, prefer PostgreSQL or MySQL. Regardless of the starting provider, keep application queries on the Prisma ORM whenever possible so schema and query behavior stay easier to migrate across providers.
|
|
67
67
|
|
|
68
68
|
## Global Prisma Configuration
|
|
69
69
|
|
|
@@ -121,7 +121,7 @@ model Post {
|
|
|
121
121
|
After changing the schema, use this order:
|
|
122
122
|
|
|
123
123
|
1. Run `npx prisma migrate dev`.
|
|
124
|
-
2. If seed data or the seed script needs the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
124
|
+
2. If seed data or the seed script needs the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
125
125
|
3. Run `npx ppy generate` to refresh the generated Python ORM classes.
|
|
126
126
|
|
|
127
127
|
Do not hand-edit generated Prisma or Python ORM output. Treat `prisma/schema.prisma` as the source of truth and regenerate from it.
|
|
@@ -131,8 +131,8 @@ Do not hand-edit generated Prisma or Python ORM output. Treat `prisma/schema.pri
|
|
|
131
131
|
Use these commands for the normal Prisma lifecycle in Caspian:
|
|
132
132
|
|
|
133
133
|
- `npx prisma migrate dev` creates and applies a development migration. This is the first command to run after changing `prisma/schema.prisma`.
|
|
134
|
-
- `npx prisma generate` compiles `schema.prisma` into the generated Node Prisma client. Run it before `npx prisma db seed` when the updated seed flow depends on the new schema.
|
|
135
|
-
- `npx prisma db seed` runs the configured seeding script. This may delete or overwrite existing database data; an AI agent must warn the user and receive explicit approval before executing it.
|
|
134
|
+
- `npx prisma generate` compiles `schema.prisma` into the generated Node Prisma client. Run it before `npx prisma db seed` when the updated seed flow depends on the new schema.
|
|
135
|
+
- `npx prisma db seed` runs the configured seeding script. This may delete or overwrite existing database data; an AI agent must warn the user and receive explicit approval before executing it.
|
|
136
136
|
- `npx ppy generate` regenerates the Python ORM classes used by the app. Use this after every schema change.
|
|
137
137
|
- `npx prisma migrate deploy` applies pending migrations in deployment environments.
|
|
138
138
|
- `npx prisma db push` syncs schema changes without creating a migration file, which is useful for prototyping.
|
|
@@ -140,7 +140,7 @@ Use these commands for the normal Prisma lifecycle in Caspian:
|
|
|
140
140
|
|
|
141
141
|
Default rule:
|
|
142
142
|
|
|
143
|
-
- When `prisma/schema.prisma` changes, use this order: `npx prisma migrate dev`; if seeding is involved, run `npx prisma generate`, ask for explicit approval before `npx prisma db seed`, then run `npx ppy generate`.
|
|
143
|
+
- When `prisma/schema.prisma` changes, use this order: `npx prisma migrate dev`; if seeding is involved, run `npx prisma generate`, ask for explicit approval before `npx prisma db seed`, then run `npx ppy generate`.
|
|
144
144
|
- Never hand-edit generated Prisma or Python ORM classes, and never replace `npx ppy generate` with a manual class update.
|
|
145
145
|
- Use migrations for tracked application changes.
|
|
146
146
|
- Use `db push` only when you intentionally want a faster, migration-free prototype loop.
|
|
@@ -173,7 +173,7 @@ If Python route or RPC code needs database access, import from `src.lib.prisma`
|
|
|
173
173
|
|
|
174
174
|
## Python Route Usage
|
|
175
175
|
|
|
176
|
-
If the project ships an app-owned Python Prisma-style layer under `src/lib/prisma/`, treat it as async-first and reuse it from route and RPC code. In a Prisma-enabled project, this is the required data-access path for Python code.
|
|
176
|
+
If the project ships an app-owned Python Prisma-style layer under `src/lib/prisma/`, treat it as async-first and reuse it from route and RPC code. In a Prisma-enabled project, this is the required data-access path for Python code.
|
|
177
177
|
|
|
178
178
|
Example:
|
|
179
179
|
|
|
@@ -194,7 +194,7 @@ Prisma calls fit naturally in:
|
|
|
194
194
|
- `async def page()` for first-render data
|
|
195
195
|
- `@rpc()` actions for browser-triggered reads and writes
|
|
196
196
|
|
|
197
|
-
Keep route-specific Prisma I/O in that route's `page()` or `@rpc()` actions in `src/app/**/index.py`. The installed layout engine supports synchronous and async `layout()` results, but layout work should stay focused on shared subtree props or metadata. Move Prisma helpers into `src/lib/**` only when the same behavior is reused by multiple routes, features, or integrations.
|
|
197
|
+
Keep route-specific Prisma I/O in that route's `page()` or `@rpc()` actions in `src/app/**/index.py`. The installed layout engine supports synchronous and async `layout()` results, but layout work should stay focused on shared subtree props or metadata. Move Prisma helpers into `src/lib/**` only when the same behavior is reused by multiple routes, features, or integrations.
|
|
198
198
|
|
|
199
199
|
See `fetch-data.md` for the recommended route-render versus RPC split.
|
|
200
200
|
|
|
@@ -332,39 +332,39 @@ async with prisma.transaction() as tx:
|
|
|
332
332
|
)
|
|
333
333
|
```
|
|
334
334
|
|
|
335
|
-
### Raw SQL Fallback
|
|
336
|
-
|
|
337
|
-
Use this escape hatch sparingly. Raw SQL is not the default query style in a Prisma-enabled Caspian project.
|
|
338
|
-
|
|
339
|
-
Before using `query_raw()` or `execute_raw()`, confirm that the generated Prisma API cannot express the query clearly with normal methods such as `find_many`, `find_unique`, `create`, `update`, `delete`, `delete_many`, `aggregate`, relation `include`, or transactions.
|
|
340
|
-
|
|
341
|
-
Important portability warning:
|
|
342
|
-
|
|
343
|
-
- Raw SQL is provider-specific. Placeholder style, identifier quoting, JSON operators, case-sensitivity rules, date functions, and aggregate behavior can differ across SQLite, MySQL, and PostgreSQL.
|
|
344
|
-
- A raw query that works in SQLite may fail after a move to PostgreSQL or MySQL even when the Prisma schema migrates cleanly.
|
|
345
|
-
- If a project may switch providers, prefer Prisma ORM methods first and treat raw SQL as an exception that needs provider-aware review.
|
|
346
|
-
|
|
347
|
-
```python
|
|
348
|
-
users = await prisma.user.find_many(
|
|
349
|
-
where={
|
|
350
|
-
"email": {"contains": "@gmail.com"},
|
|
351
|
-
},
|
|
352
|
-
)
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
If raw SQL is still unavoidable, keep it tightly scoped, document why the ORM was insufficient, and verify it against the current datasource provider in `prisma/schema.prisma`.
|
|
335
|
+
### Raw SQL Fallback
|
|
336
|
+
|
|
337
|
+
Use this escape hatch sparingly. Raw SQL is not the default query style in a Prisma-enabled Caspian project.
|
|
338
|
+
|
|
339
|
+
Before using `query_raw()` or `execute_raw()`, confirm that the generated Prisma API cannot express the query clearly with normal methods such as `find_many`, `find_unique`, `create`, `update`, `delete`, `delete_many`, `aggregate`, relation `include`, or transactions.
|
|
340
|
+
|
|
341
|
+
Important portability warning:
|
|
342
|
+
|
|
343
|
+
- Raw SQL is provider-specific. Placeholder style, identifier quoting, JSON operators, case-sensitivity rules, date functions, and aggregate behavior can differ across SQLite, MySQL, and PostgreSQL.
|
|
344
|
+
- A raw query that works in SQLite may fail after a move to PostgreSQL or MySQL even when the Prisma schema migrates cleanly.
|
|
345
|
+
- If a project may switch providers, prefer Prisma ORM methods first and treat raw SQL as an exception that needs provider-aware review.
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
users = await prisma.user.find_many(
|
|
349
|
+
where={
|
|
350
|
+
"email": {"contains": "@gmail.com"},
|
|
351
|
+
},
|
|
352
|
+
)
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
If raw SQL is still unavoidable, keep it tightly scoped, document why the ORM was insufficient, and verify it against the current datasource provider in `prisma/schema.prisma`.
|
|
356
356
|
|
|
357
357
|
## Recommended Project Rules
|
|
358
358
|
|
|
359
359
|
- Keep the schema in `prisma/schema.prisma` and follow the required regeneration order after changes: `npx prisma migrate dev`, optional seed flow, then `npx ppy generate`.
|
|
360
|
-
- Reuse `src/lib/prisma/` for Python-side database access instead of creating a second bridge.
|
|
361
|
-
- When Prisma is enabled, do not bypass the Prisma Python ORM with direct database drivers, custom fetch functions, JSON files as active stores, or browser-side database access.
|
|
360
|
+
- Reuse `src/lib/prisma/` for Python-side database access instead of creating a second bridge.
|
|
361
|
+
- When Prisma is enabled, do not bypass the Prisma Python ORM with direct database drivers, custom fetch functions, JSON files as active stores, or browser-side database access.
|
|
362
362
|
- Never hand-edit generated Prisma or Python ORM classes.
|
|
363
363
|
- Keep reusable database helpers in `src/lib/`, and keep route-specific orchestration in `src/app/`.
|
|
364
364
|
- Use `await` with Prisma operations.
|
|
365
365
|
- Convert Prisma objects to template-safe dictionaries when rendering HTML.
|
|
366
366
|
- Validate incoming mutation data before calling `create`, `update`, or `delete` operations.
|
|
367
|
-
- Prefer Prisma queries over raw SQL. If raw SQL is unavoidable, keep it provider-aware, narrowly scoped, and documented so future database-provider migrations do not silently break application behavior.
|
|
367
|
+
- Prefer Prisma queries over raw SQL. If raw SQL is unavoidable, keep it provider-aware, narrowly scoped, and documented so future database-provider migrations do not silently break application behavior.
|
|
368
368
|
|
|
369
369
|
## AI Retrieval Notes
|
|
370
370
|
|
|
@@ -373,13 +373,13 @@ If an AI agent is working on a Caspian app with Prisma enabled, apply these rule
|
|
|
373
373
|
- Treat Prisma as the default ORM and persistence layer.
|
|
374
374
|
- Read `prisma/schema.prisma` before proposing model, relation, or field changes.
|
|
375
375
|
- When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first.
|
|
376
|
-
- If the schema change requires seed data, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
376
|
+
- If the schema change requires seed data, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed`.
|
|
377
377
|
- Run `npx ppy generate` after schema changes to refresh the Python ORM classes.
|
|
378
378
|
- Never hand-edit generated Prisma or Python ORM classes.
|
|
379
379
|
- Read `prisma.config.ts` and `prisma/seed.ts` when you need the current project's Prisma tooling examples.
|
|
380
|
-
- Reuse the existing `src/lib/prisma/` package when the Python app needs database access.
|
|
381
|
-
- Treat use of the Prisma Python ORM as mandatory for Python-side database reads and writes in Prisma-enabled projects.
|
|
380
|
+
- Reuse the existing `src/lib/prisma/` package when the Python app needs database access.
|
|
381
|
+
- Treat use of the Prisma Python ORM as mandatory for Python-side database reads and writes in Prisma-enabled projects.
|
|
382
382
|
- For file managers and uploads, persist metadata in Prisma and keep blob storage separate. See [file-uploads.md](./file-uploads.md).
|
|
383
383
|
- Put reusable database helpers in `src/lib/`; keep route and RPC orchestration in `src/app/`.
|
|
384
|
-
- Use `async def page()` for route-specific first-render reads. Use `layout()` only for shared subtree props or metadata, and use `@rpc()` plus `pp.rpc()` for browser-triggered reads and writes.
|
|
384
|
+
- Use `async def page()` for route-specific first-render reads. Use `layout()` only for shared subtree props or metadata, and use `@rpc()` plus `pp.rpc()` for browser-triggered reads and writes.
|
|
385
385
|
- Check `fetch-data.md` for route versus RPC guidance and `validation.md` before writing public mutations.
|
|
@@ -47,6 +47,7 @@ If an inspected browser DOM disagrees with authored template source, remember th
|
|
|
47
47
|
| SPA navigation | `body[pp-spa="true"]`, links | `pp-reactive-v2.js`, `main.py` | same-origin eligible links intercept; root-layout mismatches hard reload |
|
|
48
48
|
| Scroll restoration | `pp-reset-scroll="true"` | `pp-reactive-v2.js` | push navigation resets window; mark only content panes that should reset |
|
|
49
49
|
| Tailwind merge | `{twMerge(...)}`, Python `merge_classes(...)` | `html_attrs.py`, `pp-reactive-v2.js` | Python emits frontend-ready expressions when Tailwind is enabled |
|
|
50
|
+
| Markup deferral | `<template pp-component>` / `<template pp-owner>` wrappers | render pipeline (`main.py`), `pp-reactive-v2.js` (`materializeTemplateComponentBoundaries`) | top-level roots ship inside an inert `<template>`; runtime materializes them on mount and SPA navigation before scanning. Browser never validates `<template>` contents, so `{...}` is safe in any attribute/position (SVG geometry, `src`/`href`, form `value`/date, table/select text) — no per-tag workarounds. See [pulsepoint.md](./pulsepoint.md) "Component markup is deferred inside an inert `<template>`" |
|
|
50
51
|
|
|
51
52
|
## AI Decision Rules
|
|
52
53
|
|
package/dist/docs/pulsepoint.md
CHANGED
|
@@ -346,12 +346,12 @@ Important:
|
|
|
346
346
|
- The script lookup walks the current root and skips nested `pp-component` boundaries, so a parent does not consume a child component's script.
|
|
347
347
|
- If multiple matching runtime scripts exist in the same root, the first matching owned script wins. Generate one script per root.
|
|
348
348
|
- Authored route, layout, and component templates still need one top-level parent node so Caspian can inject the component boundary correctly after component expansion.
|
|
349
|
-
- A scriptless component root still mounts and can receive props, refs, events, and nested children, but it does not create local bindings from those props on its own.
|
|
349
|
+
- A scriptless component root still mounts and can receive props, refs, events, and nested children, but it does not create local bindings from those props on its own.
|
|
350
350
|
- Component scripts are plain JavaScript executed with `new Function(...)`. Do not use `import`, `export`, or top-level `await` inside them.
|
|
351
351
|
- The runtime auto-returns supported top-level bindings from the script. Do not rely on manual `return { ... }` objects.
|
|
352
|
-
- `pp.props` contains the current prop bag for the component.
|
|
353
|
-
- `pp.props.children` contains the root's initial inner HTML before the owned script is removed from the render template.
|
|
354
|
-
- Props are not auto-injected as standalone top-level template or handler variables. Read them through `pp.props` or explicitly destructure them in the component script.
|
|
352
|
+
- `pp.props` contains the current prop bag for the component.
|
|
353
|
+
- `pp.props.children` contains the root's initial inner HTML before the owned script is removed from the render template.
|
|
354
|
+
- Props are not auto-injected as standalone top-level template or handler variables. Read them through `pp.props` or explicitly destructure them in the component script.
|
|
355
355
|
|
|
356
356
|
Bindings exported to the template:
|
|
357
357
|
|
|
@@ -570,13 +570,13 @@ When a child component needs the same token object, pass it from the provider sc
|
|
|
570
570
|
|
|
571
571
|
- Child component props are derived from DOM attributes.
|
|
572
572
|
- Attribute names are converted from kebab-case to camelCase for the prop bag.
|
|
573
|
-
- Native `on*` attributes and `pp-component` are not included in props.
|
|
574
|
-
- Empty attributes become boolean `true` props.
|
|
575
|
-
- Pure prop expressions such as `title="{pageTitle}"` are evaluated in the parent scope.
|
|
576
|
-
- Mixed strings such as `class="card {isActive ? 'active' : ''}"` are interpolated in the parent scope.
|
|
577
|
-
- Non-expression attribute values are passed through as strings.
|
|
578
|
-
- `children` is injected into props using the root's initial inner HTML.
|
|
579
|
-
- Inside the child component, those values should be accessed through `pp.props` or a top-level destructure such as `const { title } = pp.props`; they are not implicitly available as bare identifiers.
|
|
573
|
+
- Native `on*` attributes and `pp-component` are not included in props.
|
|
574
|
+
- Empty attributes become boolean `true` props.
|
|
575
|
+
- Pure prop expressions such as `title="{pageTitle}"` are evaluated in the parent scope.
|
|
576
|
+
- Mixed strings such as `class="card {isActive ? 'active' : ''}"` are interpolated in the parent scope.
|
|
577
|
+
- Non-expression attribute values are passed through as strings.
|
|
578
|
+
- `children` is injected into props using the root's initial inner HTML.
|
|
579
|
+
- Inside the child component, those values should be accessed through `pp.props` or a top-level destructure such as `const { title } = pp.props`; they are not implicitly available as bare identifiers.
|
|
580
580
|
|
|
581
581
|
Nested components:
|
|
582
582
|
|
|
@@ -621,6 +621,14 @@ Example:
|
|
|
621
621
|
</div>
|
|
622
622
|
```
|
|
623
623
|
|
|
624
|
+
### Component markup is deferred inside an inert `<template>`
|
|
625
|
+
|
|
626
|
+
The render pipeline wraps each top-level `pp-component` root in an inert `<template pp-component="…">`, and the runtime materializes it back into live DOM on `mount()` (and on every SPA navigation) before it scans for roots. The browser never parses, validates, or fetches the contents of a `<template>`, so raw `{...}` placeholders never reach live DOM at first paint.
|
|
627
|
+
|
|
628
|
+
- Because of this, `{...}` is safe in **any** attribute or position — including slots the browser would otherwise validate eagerly: SVG geometry (`d`, `viewBox`, `points`, `transform`), URL attributes (`src`, `srcset`, `href`, `poster`), form `value` on `date`/`number`/`color` inputs, and text placed directly inside `<table>` or `<select>`.
|
|
629
|
+
- Do not add per-tag workarounds to dodge first-paint validation (static-path `hidden` toggles instead of binding `d`, `data-*` URL holders, `hidden`-gated `<img src>`, or an SSR-resolved initial value). The deferral removes the whole class at once.
|
|
630
|
+
- `pp-style` and the `<input>`/`<select>`/`checked`/`defaultvalue`/`<textarea>` value rewrites still apply — but for different reasons that deferral does not replace: authoring-source tooling (`style="{...}"` breaks HTML/CSS linters) and attribute-vs-property correctness for controlled form fields.
|
|
631
|
+
|
|
624
632
|
## Refs
|
|
625
633
|
|
|
626
634
|
- Refs are for imperative element access. Do not use `pp-ref` as the default way to read normal form input values on submit; prefer the form's `onsubmit` event plus `Object.fromEntries(new FormData(event.currentTarget).entries())`.
|