caspian-utils 0.1.11 → 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.
@@ -103,14 +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
- npx prisma db seed
109
-
110
- npx ppy generate
111
- ```
112
-
113
- Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
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.
114
117
 
115
118
  ## 2. Script Guardrails
116
119
 
@@ -595,17 +598,18 @@ The create and update commands above are not the whole maintenance story for a P
595
598
  ```bash
596
599
  npx prisma migrate dev
597
600
 
598
- # Only when seed flow or prisma/seed.ts depends on the new schema:
599
- npx prisma generate
600
- npx prisma db seed
601
-
602
- npx ppy generate
603
- ```
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
+ ```
604
608
 
605
609
  Use this order:
606
610
 
607
611
  1. Run `npx prisma migrate dev` first so migrations and the development database stay aligned.
608
- 2. If `prisma/seed.ts` or seed data depends on the new schema, run `npx prisma generate` and then `npx prisma db seed`.
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.
609
613
  3. Run `npx ppy generate` last so the generated Python ORM layer matches the updated Prisma schema.
610
614
 
611
615
  Do not manually create or edit these generated files:
@@ -678,7 +682,7 @@ If an AI agent is deciding which command flow to use, apply these rules first.
678
682
  - Treat `--tailwindcss` and `--typescript` as frontend-oriented flags. They are not meaningful in normal backend-only scaffolds.
679
683
  - Treat starter kit defaults as a base layer that can be overridden by explicit flags.
680
684
  - Read `caspian.config.json` before running update commands.
681
- - When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first, then any required seed refresh, then `npx ppy generate`.
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.
682
686
  - Never hand-edit generated Python ORM files under `src/lib/prisma/` or `settings/prisma-schema.json`.
683
687
  - Read [database.md](./database.md) before generating Prisma schema, migration, seed, or ORM guidance.
684
688
  - Read [routing.md](./routing.md) before generating or modifying route folders under `src/app/`.
@@ -22,16 +22,30 @@ Treat `caspian.config.json` as the single source of truth for whether Prisma is
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` and then `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
-
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
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.
35
49
 
36
50
  ## Environment Setup
37
51
 
@@ -107,7 +121,7 @@ model Post {
107
121
  After changing the schema, use this order:
108
122
 
109
123
  1. Run `npx prisma migrate dev`.
110
- 2. If seed data or the seed script needs the new schema, run `npx prisma generate` and then `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`.
111
125
  3. Run `npx ppy generate` to refresh the generated Python ORM classes.
112
126
 
113
127
  Do not hand-edit generated Prisma or Python ORM output. Treat `prisma/schema.prisma` as the source of truth and regenerate from it.
@@ -117,8 +131,8 @@ Do not hand-edit generated Prisma or Python ORM output. Treat `prisma/schema.pri
117
131
  Use these commands for the normal Prisma lifecycle in Caspian:
118
132
 
119
133
  - `npx prisma migrate dev` creates and applies a development migration. This is the first command to run after changing `prisma/schema.prisma`.
120
- - `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.
121
- - `npx prisma db seed` runs the configured seeding script.
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.
122
136
  - `npx ppy generate` regenerates the Python ORM classes used by the app. Use this after every schema change.
123
137
  - `npx prisma migrate deploy` applies pending migrations in deployment environments.
124
138
  - `npx prisma db push` syncs schema changes without creating a migration file, which is useful for prototyping.
@@ -126,7 +140,7 @@ Use these commands for the normal Prisma lifecycle in Caspian:
126
140
 
127
141
  Default rule:
128
142
 
129
- - When `prisma/schema.prisma` changes, use this order: `npx prisma migrate dev`; if seeding is involved, run `npx prisma generate` and `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`.
130
144
  - Never hand-edit generated Prisma or Python ORM classes, and never replace `npx ppy generate` with a manual class update.
131
145
  - Use migrations for tracked application changes.
132
146
  - Use `db push` only when you intentionally want a faster, migration-free prototype loop.
@@ -359,7 +373,7 @@ If an AI agent is working on a Caspian app with Prisma enabled, apply these rule
359
373
  - Treat Prisma as the default ORM and persistence layer.
360
374
  - Read `prisma/schema.prisma` before proposing model, relation, or field changes.
361
375
  - When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first.
362
- - If the schema change requires seed data, run `npx prisma generate` and then `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`.
363
377
  - Run `npx ppy generate` after schema changes to refresh the Python ORM classes.
364
378
  - Never hand-edit generated Prisma or Python ORM classes.
365
379
  - Read `prisma.config.ts` and `prisma/seed.ts` when you need the current project's Prisma tooling examples.
@@ -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
 
@@ -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())`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "caspian-utils",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Caspian tooling",
5
5
  "main": "index.js",
6
6
  "scripts": {