@polymorphism-tech/morph-spec 8.46.0 → 8.47.0

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.
Files changed (140) hide show
  1. package/CLAUDE.md +5 -5
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +1 -4
  4. package/bin/validate.js +4 -25
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -2
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +1 -1
  9. package/framework/MORPH.md +8 -8
  10. package/framework/commands/create-umbraco-lp.md +2 -0
  11. package/framework/commands/migrate-lp-to-umbraco.md +2 -0
  12. package/framework/commands/morph-archive.md +1 -1
  13. package/framework/commands/morph-hotfix.md +1 -1
  14. package/framework/commands/morph-infra.md +17 -203
  15. package/framework/commands/morph-media.md +3 -0
  16. package/framework/commands/morph-preflight.md +5 -28
  17. package/framework/commands/morph-proposal.md +2 -2
  18. package/framework/commands/morph-troubleshoot.md +2 -14
  19. package/framework/docs/CLI.md +3 -3
  20. package/framework/hooks/claude-code/core/state-sync.js +13 -1
  21. package/framework/hooks/shared/e2e-check.js +3 -4
  22. package/framework/hooks/shared/state-writer.js +1 -0
  23. package/framework/rules/ai-agents-standards.md +18 -16
  24. package/framework/rules/asaas-standards.md +3 -1
  25. package/framework/rules/csharp-standards.md +10 -8
  26. package/framework/rules/data-standards.md +5 -5
  27. package/framework/rules/dotnet-templates.md +1 -1
  28. package/framework/rules/frontend-standards.md +4 -2
  29. package/framework/rules/gsap-standards.md +10 -5
  30. package/framework/rules/hangfire-standards.md +3 -1
  31. package/framework/rules/infrastructure-standards.md +4 -2
  32. package/framework/rules/morph-workflow.md +2 -2
  33. package/framework/rules/neon-auth-standards.md +3 -1
  34. package/framework/rules/neon-standards.md +6 -4
  35. package/framework/rules/nextjs-standards.md +13 -11
  36. package/framework/rules/nextjs-templates.md +1 -1
  37. package/framework/rules/resend-standards.md +3 -1
  38. package/framework/schemas/feature.schema.json +1 -3
  39. package/framework/skills/README.md +1 -1
  40. package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
  41. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
  42. package/framework/skills/core/morph-apply/SKILL.md +3 -3
  43. package/framework/skills/core/morph-brainstorming/SKILL.md +3 -3
  44. package/framework/skills/core/morph-hotfix/SKILL.md +4 -4
  45. package/framework/skills/core/morph-implement/SKILL.md +3 -3
  46. package/framework/skills/core/morph-machine/SKILL.md +3 -3
  47. package/framework/skills/core/morph-media/SKILL.md +3 -3
  48. package/framework/skills/core/morph-plan/SKILL.md +3 -3
  49. package/framework/skills/core/morph-proposal/SKILL.md +3 -3
  50. package/framework/skills/core/morph-review/SKILL.md +3 -3
  51. package/framework/skills/core/morph-stack-scan/SKILL.md +3 -3
  52. package/framework/skills/core/morph-standards/SKILL.md +6 -6
  53. package/framework/skills/core/morph-uiux/SKILL.md +3 -3
  54. package/framework/standards/STANDARDS.json +59 -56
  55. package/framework/standards/ai-agents/evals-with-cache.md +1 -1
  56. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  57. package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
  58. package/framework/standards/ai-agents/prompt-sources.md +6 -4
  59. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  60. package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
  61. package/framework/standards/ai-agents/setup.md +1 -1
  62. package/framework/standards/ai-agents/structured-output.md +1 -1
  63. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  64. package/framework/standards/architecture/code-comments.md +2 -2
  65. package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
  66. package/framework/standards/backend/api/validation.md +135 -47
  67. package/framework/standards/backend/database/postgresql/database.md +11 -7
  68. package/framework/standards/backend/database/vector-search-rag.md +207 -324
  69. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
  70. package/framework/standards/backend/dotnet/result-pattern.md +40 -6
  71. package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
  72. package/framework/standards/backend/dotnet/scrutor.md +1 -1
  73. package/framework/standards/backend/dotnet/testing.md +1 -1
  74. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
  75. package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
  76. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
  77. package/framework/standards/data/nosql/cache/redis.md +120 -44
  78. package/framework/standards/data/nosql/cosmos-db.md +114 -71
  79. package/framework/standards/frontend/design-system/animations.md +1 -1
  80. package/framework/standards/frontend/design-system/naming.md +1 -1
  81. package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
  82. package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
  83. package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
  84. package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
  85. package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
  86. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  87. package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
  88. package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
  89. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
  90. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
  91. package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
  92. package/framework/templates/infrastructure/github/README.md +2 -1
  93. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
  94. package/package.json +1 -1
  95. package/src/commands/observability/telemetry.js +3 -5
  96. package/src/commands/project/init.js +2 -1
  97. package/src/commands/project/update.js +16 -18
  98. package/src/commands/state/approve.js +17 -0
  99. package/src/commands/state/gate-check.js +4 -14
  100. package/src/commands/validation/verify.js +3 -12
  101. package/src/core/paths/output-schema.js +1 -1
  102. package/src/dashboard/app/App.jsx +0 -2
  103. package/src/dashboard/app/components/CommandPalette.jsx +2 -3
  104. package/src/dashboard/app/components/EntityLink.jsx +0 -1
  105. package/src/dashboard/app/components/Markdown.jsx +1 -1
  106. package/src/dashboard/app/components/Sidebar.jsx +1 -2
  107. package/src/dashboard/app/pages/RulesMap.jsx +3 -3
  108. package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
  109. package/src/dashboard/scanner/activity-scanner.js +1 -1
  110. package/src/dashboard/scanner/docs-scanner.js +5 -23
  111. package/src/dashboard/scanner/features-scanner.js +1 -1
  112. package/src/dashboard/scanner/index.js +0 -2
  113. package/src/dashboard/scanner/rules-scanner.js +15 -10
  114. package/src/dashboard/scanner/skills-scanner.js +2 -3
  115. package/src/lib/evaluator-report.js +13 -0
  116. package/src/lib/risk-detector.js +8 -0
  117. package/src/lib/stack/stack-profile.js +1 -1
  118. package/src/lib/validators/reuse/reuse-validator.js +2 -3
  119. package/src/lib/validators/reuse/symbol-scanner.js +2 -4
  120. package/src/lib/validators/validation-runner.js +8 -88
  121. package/src/lib/validators/verify-runner.js +22 -72
  122. package/src/scripts/setup-infra.js +33 -22
  123. package/src/utils/agents-installer.js +20 -8
  124. package/src/utils/file-copier.js +7 -5
  125. package/framework/commands/commit.md +0 -166
  126. package/framework/rubrics/backend.json +0 -41
  127. package/framework/rubrics/default.json +0 -36
  128. package/framework/rubrics/frontend.json +0 -36
  129. package/framework/templates/project/validate.js +0 -97
  130. package/src/dashboard/app/pages/Rubrics.jsx +0 -97
  131. package/src/dashboard/scanner/rubrics-scanner.js +0 -12
  132. package/src/lib/validators/architecture/architecture-validator.js +0 -270
  133. package/src/lib/validators/architecture/index.js +0 -7
  134. package/src/lib/validators/css/css-validator.js +0 -340
  135. package/src/lib/validators/css/index.js +0 -7
  136. package/src/lib/validators/design-system/design-system-validator.js +0 -237
  137. package/src/lib/validators/design-system/index.js +0 -7
  138. package/src/lib/validators/score-aggregator.js +0 -244
  139. package/src/lib/validators/ui/index.js +0 -7
  140. package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
@@ -1,91 +1,179 @@
1
- # Status Validation Pattern
1
+ # Request Validation — DTO Validation in the Slice
2
2
 
3
3
  > **Scope:** universal
4
- > **Layer:** 0 (always load)
4
+ > **Layer:** 0 (resumo injetado pela rule `csharp-standards` ao editar `**/*.cs`/`**/*.csproj`; texto completo sob demanda via `morph-spec standards --find`)
5
5
  > **Keywords:** validation, fluent, dto, modelstate, fluentvalidation
6
6
  > **Load When:** always
7
7
 
8
- **Verified against:** .NET 10 (pure state-validation pattern — no external package). Last-verified: 2026-05-20.
8
+ **Verified against:** .NET 10 (SDK 10.0.400-preview) + FluentValidation 12.1.1 + EF Core 10.0.12. The validator, `OrderStatus`, `OrderErrors` and state-check handler blocks compile with `TreatWarningsAsErrors` over the `Result`/`Error`/`ValidationError` of `result-pattern.md`. Last-verified: 2026-10-03.
9
9
 
10
10
  ---
11
11
 
12
- **MORPH-SPEC Standard** — Validate what is INVALID, not what is valid.
12
+ **MORPH-SPEC Standard** — every request DTO is validated in its own slice, before the handler runs, and a failure leaves as a `Result`, never as an exception.
13
13
 
14
- ## Problem
14
+ ## Where each check lives
15
15
 
16
- Validations assuming a single flow break when new flows are added.
16
+ | Check | Lives in | Fails as | HTTP (via `error.ToHttpResult()`) |
17
+ |-------|----------|----------|-----------------------------------|
18
+ | Request **shape**: required, length, range, format, enum, CPF/CNPJ | `{Verb}{Entity}Validator : AbstractValidator<TRequest>` in the slice folder | `ValidationError` (aggregated `Error.Validation` items) from the `ValidationDecorator` | 400 ProblemDetails with `errors[]` |
19
+ | Needs the database: entity exists, unique value | The handler, after loading | `Error.NotFound` / `Error.Conflict` | 404 / 409 |
20
+ | Entity **state** allows the operation (order not completed, not cancelled) | The handler (see *State checks in the handler*) | `Error.Failure` / `Error.Conflict` | 400 / 409 |
17
21
 
22
+ `ModelState` does not exist in minimal APIs, and DataAnnotations on the request plus FluentValidation would be two validators disagreeing about the same DTO: the stack uses FluentValidation through the decorator, only.
23
+
24
+ ## FluentValidation Validator in the Slice
25
+
26
+ ```csharp
27
+ // Features/OrderFeature/CreateOrder/CreateOrderValidator.cs
28
+ using FluentValidation;
29
+
30
+ public sealed record CreateOrderItem(Guid ProductId, int Quantity);
31
+ public sealed record CreateOrderRequest(Guid CustomerId, string? CouponCode, IReadOnlyList<CreateOrderItem> Items);
32
+
33
+ public sealed class CreateOrderValidator : AbstractValidator<CreateOrderRequest>
34
+ {
35
+ public CreateOrderValidator()
36
+ {
37
+ RuleFor(r => r.CustomerId).NotEmpty();
38
+
39
+ RuleFor(r => r.CouponCode)
40
+ .MaximumLength(32)
41
+ .Matches("^[A-Z0-9-]+$").WithMessage("Coupon code must be upper-case letters, digits or '-'.")
42
+ .When(r => r.CouponCode is not null);
43
+
44
+ RuleFor(r => r.Items)
45
+ .NotEmpty().WithMessage("An order needs at least one item.");
46
+
47
+ RuleForEach(r => r.Items).ChildRules(item =>
48
+ {
49
+ item.RuleFor(i => i.ProductId).NotEmpty();
50
+ item.RuleFor(i => i.Quantity).InclusiveBetween(1, 100);
51
+ });
52
+ }
53
+ }
18
54
  ```
19
- Original: Created → PendingPayment → Processing → Completed → EmailSent
20
- Free: Created → Processing → Completed → EmailSent (skips payment)
55
+
56
+ - One validator per request, `sealed`, next to the handler; no validator for a request without input (GetAll).
57
+ - Validate the **shape** only. "Does this customer exist?" needs the database and is the handler's job (a validator with a `DbContext` runs a query per rule and still cannot see a concurrent write).
58
+ - Time-dependent rules take `TimeProvider` and read it inside the rule (`LessThanOrEqualTo(_ => timeProvider.GetUtcNow().Year)`), never `DateTime.UtcNow`.
59
+
60
+ ## How a failure reaches HTTP
61
+
62
+ ```
63
+ request ─→ ValidationDecorator ─→ any failure? ─yes─→ Result.Failure(new ValidationError([...])) ─→ endpoint: error.ToHttpResult() ─→ 400 + errors[]
64
+ │
65
+ no
66
+ ↓
67
+ handler ─→ Result<T>
21
68
  ```
22
69
 
23
- ```csharp
24
- // ❌ Assumes single flow — breaks free flow
25
- if (order.Status != OrderStatus.PendingPayment)
26
- throw new InvalidOperationException("Must be pending payment");
70
+ The decorator, its registration (`AddValidatorsFromAssembly` before `AddHandlersFromAssembly`) and the `ValidationFailure` → `Error.Validation` conversion are in `backend/dotnet/fluent-validation-vsa.md`; the `ValidationError` record and `ErrorHttpMapping.ToHttpResult()` (which puts the items in the ProblemDetails `errors` extension) are in `backend/dotnet/result-pattern.md`. The endpoint never inspects the error itself.
71
+
72
+ ## Validation Patterns
73
+
74
+ | Rule | Why |
75
+ |------|-----|
76
+ | Validate in the slice's validator, never in the endpoint lambda | One place per request; the endpoint only maps HTTP |
77
+ | Return `Result`, never `throw` (`ValidationException`, `ArgumentException`) | Exceptions as flow are forbidden; the decorator already short-circuits with a `ValidationError` |
78
+ | Aggregate all failures | The client fixes every field in one round-trip |
79
+ | Message per rule that the UI can show | `errors[].description` is what the form displays |
80
+ | Shape in the validator, existence/uniqueness/state in the handler | The validator has no reliable view of the database |
27
81
 
28
- // ✅ Validates invalid states — works for all flows
29
- if (order.Status >= OrderStatus.Completed || order.Status == OrderStatus.Failed)
30
- throw new InvalidOperationException("Order already completed or failed");
82
+ ## State checks in the handler
83
+
84
+ Some operations depend on the entity's **state**, not the request's shape. That check lives in the handler, after loading the entity, and returns a `Result`. The rule: validate what is INVALID, not what is valid, so a new flow does not break existing checks.
85
+
86
+ ```
87
+ Original: Created → PendingPayment → Processing → Completed → EmailSent
88
+ Free: Created → Processing → Completed → EmailSent (skips payment)
31
89
  ```
32
90
 
33
- ## Enum Design
91
+ `if (order.Status != OrderStatus.PendingPayment)` assumes the single original flow and rejects every free order; `if (order.Status >= OrderStatus.Completed)` blocks what is actually invalid and works for both flows.
92
+
93
+ ### Enum Design
34
94
 
35
95
  ```csharp
36
96
  public enum OrderStatus
37
97
  {
38
98
  Created = 0, PendingPayment = 1, Processing = 2, Completed = 3, EmailSent = 4,
39
- // Error states (separated range)
40
99
  Failed = 100, Cancelled = 101, Refunded = 102
41
100
  }
42
101
  ```
43
102
 
44
- ## Validation Patterns
103
+ Progress states are ordered; error states sit in a separate range (100+), so `status >= OrderStatus.Completed` covers "finished or failed" in one comparison.
104
+
105
+ ### State Check Patterns
45
106
 
46
107
  | Pattern | When | Example |
47
108
  |---------|------|---------|
48
- | Final state check | Block after completion | `if (status >= OrderStatus.Completed)` |
49
- | Error state list | Block specific errors | `if (new[] { Failed, Cancelled, Refunded }.Contains(status))` |
50
- | Range comparison | Block finalized + errors | `if (status >= Completed \|\| status >= Failed)` |
109
+ | Final state check | Block after completion (includes the 100+ error range) | `if (status >= OrderStatus.Completed)` |
110
+ | Error state list | Block specific errors only | `if (status is OrderStatus.Failed or OrderStatus.Cancelled or OrderStatus.Refunded)` |
111
+ | Error range | Block every error state | `if (status >= OrderStatus.Failed)` |
51
112
 
52
- ## Anti-Patterns
53
-
54
- | Anti-Pattern | Problem | Fix |
55
- |-------------|---------|-----|
56
- | `if (status != Expected)` | Assumes single flow | Validate invalid states instead |
57
- | Exhaustive switch on valid states | Must modify for each new status | Validate only invalid states |
58
- | Business logic in state validator | Mixed concerns | Separate state validation from business rules |
59
-
60
- ## Complete Example
113
+ ### Complete Example
61
114
 
62
115
  ```csharp
63
- public async Task<Result> ProcessOrderAsync(Guid orderId, CancellationToken ct)
116
+ // Features/OrderFeature/OrderErrors.cs
117
+ public static class OrderErrors
64
118
  {
65
- var order = await _db.Orders.FindAsync([orderId], ct);
66
- if (order == null) return Result.Failure("Order not found");
119
+ public static Error NotFound(Guid orderId) =>
120
+ Error.NotFound("Orders.NotFound", $"The Order with Id '{orderId}' was not found");
121
+ public static readonly Error AlreadyFinished =
122
+ Error.Conflict("Orders.AlreadyFinished", "The order is already completed or in an error state.");
123
+ public static readonly Error PaymentRequired =
124
+ Error.Failure("Orders.PaymentRequired", "The order must be paid before processing.");
125
+ }
126
+ ```
67
127
 
68
- // State validation (invalid states)
69
- if (order.Status >= OrderStatus.Completed) return Result.Failure("Already completed");
70
- if (order.Status == OrderStatus.Failed) return Result.Failure("Cannot process failed order");
71
- if (order.Status == OrderStatus.Cancelled) return Result.Failure("Cannot process cancelled order");
128
+ ```csharp
129
+ // Features/OrderFeature/ProcessOrder/ProcessOrderHandler.cs
130
+ using Microsoft.EntityFrameworkCore;
72
131
 
73
- // Business validation (separate)
74
- if (order.RequiresPayment && !order.IsPaid) return Result.Failure("Payment required");
132
+ public sealed record ProcessOrderRequest(Guid OrderId);
75
133
 
76
- order.MarkAsProcessing();
77
- await _db.SaveChangesAsync(ct);
78
- return Result.Success();
134
+ public sealed class ProcessOrderHandler(ApplicationDbContext db) : IHandler<ProcessOrderRequest, Result>
135
+ {
136
+ public async Task<Result> HandleAsync(ProcessOrderRequest request, CancellationToken cancellationToken)
137
+ {
138
+ var order = await db.Orders.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
139
+ if (order is null)
140
+ return OrderErrors.NotFound(request.OrderId);
141
+
142
+ if (order.Status >= OrderStatus.Completed)
143
+ return OrderErrors.AlreadyFinished;
144
+
145
+ if (order.RequiresPayment && !order.IsPaid)
146
+ return OrderErrors.PaymentRequired;
147
+
148
+ order.Status = OrderStatus.Processing;
149
+ await db.SaveChangesAsync(cancellationToken);
150
+ return Result.Success();
151
+ }
79
152
  }
80
153
  ```
81
154
 
155
+ The state check (`>= Completed`) and the business rule (`RequiresPayment && !IsPaid`) stay separate lines with separate errors: the free flow passes the first and skips the second.
156
+
157
+ ## Anti-Patterns
158
+
159
+ | Anti-Pattern | Problem | Fix |
160
+ |-------------|---------|-----|
161
+ | `throw new ValidationException(...)` / `throw new InvalidOperationException(...)` for bad input or state | Exceptions as flow; bypasses the `Result` mapping | Validator → `ValidationError`; handler → typed `Error` |
162
+ | Validation inside the endpoint lambda | Logic leaks out of the slice, not reusable by jobs | `AbstractValidator<TRequest>` in the slice |
163
+ | DataAnnotations + FluentValidation on the same DTO | Two sources of truth | FluentValidation only |
164
+ | `Result.Failure("message")` with a bare string | Does not compile against the `Error` record and has no code/type | Typed `{Entity}Errors` factories |
165
+ | `if (status != Expected)` | Assumes single flow | Validate invalid states instead |
166
+ | Exhaustive switch on valid states | Must modify for each new status | Validate only invalid states |
167
+ | Business rules mixed into the state check | Mixed concerns | Separate state check from business rules |
168
+
82
169
  ## Checklist
83
170
 
84
- - [ ] Validates INVALID states (not valid)?
85
- - [ ] Uses ordered enum comparison where possible?
86
- - [ ] Error states treated separately (100+ range)?
87
- - [ ] All flows documented in decisions.md?
88
- - [ ] Tested with all possible flows?
171
+ - [ ] Every request with input has a `sealed` validator in its slice folder?
172
+ - [ ] Validator checks shape only (no `DbContext`)?
173
+ - [ ] Failures come back as `ValidationError` → 400 ProblemDetails with `errors[]`, never an exception?
174
+ - [ ] Existence / uniqueness / state checks in the handler, returning typed `Error`s?
175
+ - [ ] State checks validate INVALID states, with the error range at 100+?
176
+ - [ ] All flows documented in decisions.md and tested?
89
177
 
90
178
  ---
91
179
 
@@ -5,7 +5,7 @@
5
5
  > **Keywords:** postgresql, postgres, sql, neon, database schema
6
6
  > **Load When:** neon or postgresql keywords detected
7
7
 
8
- **Verified against:** PostgreSQL 16/17 + EF Core 10 + @neondatabase/serverless. Last-verified: 2026-05-20.
8
+ **Verified against:** PostgreSQL 16/17 + EF Core 10.0.12 (Npgsql provider 10.0.3) + @neondatabase/serverless. The EF Core query blocks compile with `TreatWarningsAsErrors` inside a wrapper method over stand-in entities; the SQL is documentary. Last-verified: 2026-10-03.
9
9
 
10
10
  ---
11
11
 
@@ -21,7 +21,7 @@ Database schema design, migrations, and Row Level Security (RLS) patterns for Ne
21
21
  |---------|-----------|---------|
22
22
  | **Tables** | snake_case, plural | `users`, `user_profiles`, `order_items` |
23
23
  | **Columns** | snake_case | `created_at`, `user_id`, `is_active` |
24
- | **Primary Keys** | `id` | `id uuid primary key default gen_random_uuid()` |
24
+ | **Primary Keys** | `id` | `id uuid primary key` -- value set by the app with `Guid.CreateVersion7()`, no column default |
25
25
  | **Foreign Keys** | `{table}_id` | `user_id`, `order_id` |
26
26
  | **Timestamps** | `created_at`, `updated_at` | Always include |
27
27
  | **Boolean** | `is_` or `has_` prefix | `is_active`, `has_verified_email` |
@@ -29,9 +29,11 @@ Database schema design, migrations, and Row Level Security (RLS) patterns for Ne
29
29
 
30
30
  ### Standard Table Template
31
31
 
32
+ Application ids are generated by the .NET handler with `Guid.CreateVersion7()` (time-ordered, index-friendly), so the column has **no** `default gen_random_uuid()`: one generator per id (the app), and random v4 values would scatter the B-tree index that v7 keeps append-mostly. A row inserted outside the app (seed script, SQL console) passes an explicit id.
33
+
32
34
  ```sql
33
35
  create table public.users (
34
- id uuid primary key default gen_random_uuid(),
36
+ id uuid primary key,
35
37
  email text unique not null,
36
38
  full_name text,
37
39
  avatar_url text,
@@ -135,7 +137,7 @@ dotnet ef migrations script --idempotent
135
137
  ```sql
136
138
  -- Create table
137
139
  create table if not exists public.example_table (
138
- id uuid primary key default gen_random_uuid(),
140
+ id uuid primary key,
139
141
  name text not null,
140
142
  created_at timestamptz default now() not null
141
143
  );
@@ -164,7 +166,7 @@ create index if not exists idx_example_table_name
164
166
 
165
167
  ```sql
166
168
  create table public.posts (
167
- id uuid primary key default gen_random_uuid(),
169
+ id uuid primary key,
168
170
  author_id uuid references public.users(id) on delete cascade,
169
171
  title text not null,
170
172
  content text,
@@ -274,7 +276,7 @@ var users = await db.Users
274
276
  ### Insert (EF Core)
275
277
 
276
278
  ```csharp
277
- var user = new User { Name = "John", Email = "john@example.com" };
279
+ var user = new User { Id = Guid.CreateVersion7(), Name = "John", Email = "john@example.com" };
278
280
  db.Users.Add(user);
279
281
  await db.SaveChangesAsync(ct);
280
282
  ```
@@ -310,7 +312,9 @@ var posts = await db.Posts
310
312
  .ToListAsync(ct);
311
313
  ```
312
314
 
313
- ### Direct SQL via Npgsql (Next.js / serverless)
315
+ ### Direct SQL from a Node runtime (@neondatabase/serverless)
316
+
317
+ In the baked stack the Next.js frontend reads data through the .NET API (proxy + TanStack Query), not from the database. This driver is for Node-side tooling (seed scripts, one-off jobs) where there is no .NET API in the path:
314
318
 
315
319
  ```typescript
316
320
  import { neon } from '@neondatabase/serverless';