@polymorphism-tech/morph-spec 4.16.0 → 4.18.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 (107) hide show
  1. package/CLAUDE.md +36 -0
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +3 -0
  4. package/bin/task-manager.js +999 -962
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/agents/ai-agents/vector-search-expert.md +247 -233
  9. package/framework/agents/backend/ms-agent-expert.md +1 -1
  10. package/framework/agents/backend/neon-expert.md +379 -0
  11. package/framework/agents/frontend/gsap-animator.md +131 -0
  12. package/framework/agents/integrations/neon-auth.md +151 -0
  13. package/framework/agents.json +1183 -1085
  14. package/framework/commands/morph-preflight.md +200 -192
  15. package/framework/hooks/claude-code/session-start/inject-morph-context.js +1 -1
  16. package/framework/rules/gsap-standards.md +13 -0
  17. package/framework/rules/neon-auth-standards.md +13 -0
  18. package/framework/rules/neon-standards.md +26 -0
  19. package/framework/skills/level-0-meta/mcp-registry.json +1 -1
  20. package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +472 -472
  21. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +1 -1
  22. package/framework/skills/level-0-meta/morph-init/SKILL.md +12 -12
  23. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +5 -5
  24. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +5 -5
  25. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +7 -7
  26. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +24 -24
  27. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +12 -12
  28. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +9 -9
  29. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +1 -1
  30. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +1 -1
  31. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -143
  32. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +1 -1
  33. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  34. package/framework/standards/STANDARDS.json +197 -116
  35. package/framework/standards/ai-agents/production.md +1 -0
  36. package/framework/standards/ai-agents/setup.md +3 -2
  37. package/framework/standards/ai-agents/workflows.md +1 -0
  38. package/framework/standards/architecture/vertical-slice/vertical-slice.md +4 -4
  39. package/framework/standards/backend/database/postgresql/database.md +63 -83
  40. package/framework/standards/backend/dotnet/scalar-ui.md +172 -172
  41. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -274
  42. package/framework/standards/backend/integrations/asaas/asaas-api.md +2 -2
  43. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +364 -0
  44. package/framework/standards/frontend/design-system/animations.md +9 -0
  45. package/framework/standards/frontend/gsap/gsap-core.md +463 -0
  46. package/framework/standards/frontend/gsap/gsap-plugins.md +294 -0
  47. package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +318 -0
  48. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -0
  49. package/framework/standards/frontend/nextjs/nextjs-patterns.md +47 -37
  50. package/framework/standards/infrastructure/docker/easypanel-deploy.md +4 -8
  51. package/framework/standards/infrastructure/neon/neon-pgrag.md +239 -0
  52. package/framework/standards/infrastructure/neon/neon-pgvector.md +236 -0
  53. package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +310 -0
  54. package/framework/standards/infrastructure/neon/neon-setup.md +186 -0
  55. package/framework/standards/integration/mcp/mcp-tools.md +32 -34
  56. package/framework/templates/README.md +20 -20
  57. package/framework/templates/REGISTRY.json +54 -101
  58. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  59. package/framework/templates/code/dotnet/backend/repository.cs +148 -148
  60. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  61. package/framework/templates/code/dotnet/database/vector-entity.cs +93 -0
  62. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +1 -1
  63. package/framework/templates/code/sql/{supabase-migration.sql → postgresql-migration.sql} +12 -21
  64. package/framework/templates/code/sql/{supabase-migration.template.sql → postgresql-migration.template.sql} +13 -18
  65. package/framework/templates/code/sql/{rls-policy.sql → postgresql-rls-policy.sql} +6 -9
  66. package/framework/templates/code/typescript/contracts.ts +167 -168
  67. package/framework/templates/context/CONTEXT.md +3 -3
  68. package/framework/templates/docs/proposal.md +6 -6
  69. package/framework/templates/docs/ui-components.md +1 -1
  70. package/framework/templates/feature/decisions.md +122 -121
  71. package/framework/templates/feature/recap.md +145 -145
  72. package/framework/templates/feature/tasks.md +199 -199
  73. package/framework/templates/frontend/nextjs/gsap-scroll-section.tsx.hbs +44 -0
  74. package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -67
  75. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  76. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  77. package/framework/templates/infrastructure/docker/easypanel.template.json +46 -54
  78. package/framework/templates/infrastructure/github/README.md +56 -56
  79. package/framework/templates/integrations/neon-auth-config.cs +133 -0
  80. package/framework/templates/integrations/semantic-kernel-neon.cs +125 -0
  81. package/framework/workflows/README.md +1 -1
  82. package/framework/workflows/docs/full-morph.md +69 -69
  83. package/package.json +1 -1
  84. package/src/commands/agents/dispatch-agents.js +19 -15
  85. package/src/commands/state/advance-phase.js +5 -0
  86. package/src/commands/tasks/task.js +3 -0
  87. package/src/core/state/state-manager.js +45 -1
  88. package/src/core/templates/template-registry.js +1 -66
  89. package/src/lib/detectors/index.js +4 -4
  90. package/src/lib/generators/architecture-scanner.js +639 -640
  91. package/src/lib/installers/mcp-installer.js +1 -1
  92. package/src/lib/tasks/task-classifier.js +15 -1
  93. package/src/lib/tasks/test-runner.js +5 -1
  94. package/src/lib/validators/content/content-validator.js +9 -10
  95. package/src/lib/validators/validation-runner.js +7 -5
  96. package/framework/agents/backend/supabase-expert.md +0 -256
  97. package/framework/agents/integrations/clerk-auth.md +0 -109
  98. package/framework/rules/clerk-standards.md +0 -13
  99. package/framework/rules/supabase-standards.md +0 -29
  100. package/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  101. package/framework/standards/infrastructure/supabase/mcp-setup.md +0 -142
  102. package/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  103. package/framework/standards/infrastructure/supabase/supabase-custom-jwt.md +0 -206
  104. package/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  105. package/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  106. package/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  107. package/framework/templates/integrations/clerk-config.cs +0 -217
@@ -1,148 +1,148 @@
1
- // ============================================================
2
- // REPOSITORY + UNIT OF WORK TEMPLATE (VSA Pattern)
3
- // Generated by MORPH Framework
4
- // ============================================================
5
-
6
- using System.Data.Common;
7
- using Microsoft.EntityFrameworkCore;
8
- using {{pascalCase PROJECT_NAME}}.Database;
9
-
10
- namespace {{pascalCase PROJECT_NAME}}.Repository;
11
-
12
- // ============================================================
13
- // IRepository<T> — Generic repository contract
14
- // ============================================================
15
-
16
- public interface IRepository<T> where T : class
17
- {
18
- Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default);
19
- Task<T?> GetByIdAsync(object id, CancellationToken cancellationToken = default);
20
- Task<T> AddAsync(T entity, CancellationToken cancellationToken = default);
21
- Task UpdateAsync(T entity, CancellationToken cancellationToken = default);
22
- Task DeleteAsync(T entity, CancellationToken cancellationToken = default);
23
- IEnumerable<T> ExecuteQuery(string query, DbParameter[] dbParams);
24
- Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default);
25
- void RemoveRange(IEnumerable<T> entities);
26
- }
27
-
28
- // ============================================================
29
- // IUnitOfWork — Transaction boundary contract
30
- // ============================================================
31
-
32
- public interface IUnitOfWork
33
- {
34
- int Commit();
35
- void Rollback();
36
- Task<int> CommitAsync(CancellationToken cancellationToken = default);
37
- Task RollbackAsync();
38
- }
39
-
40
- // ============================================================
41
- // Repository<T> — EF Core generic repository implementation
42
- // ============================================================
43
-
44
- public class Repository<T> : IRepository<T> where T : class
45
- {
46
- private readonly ApplicationDbContext _context;
47
- private readonly DbSet<T> _dbSet;
48
-
49
- public Repository(ApplicationDbContext context)
50
- {
51
- _context = context;
52
- _dbSet = _context.Set<T>();
53
- }
54
-
55
- public async Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default)
56
- {
57
- return await _dbSet.ToListAsync(cancellationToken);
58
- }
59
-
60
- public async Task<T?> GetByIdAsync(object id, CancellationToken cancellationToken = default)
61
- {
62
- return await _dbSet.FindAsync(new[] { id }, cancellationToken);
63
- }
64
-
65
- public async Task<T> AddAsync(T entity, CancellationToken cancellationToken = default)
66
- {
67
- await _dbSet.AddAsync(entity, cancellationToken);
68
- return entity;
69
- }
70
-
71
- public Task UpdateAsync(T entity, CancellationToken cancellationToken = default)
72
- {
73
- _dbSet.Update(entity);
74
- return Task.CompletedTask;
75
- }
76
-
77
- public Task DeleteAsync(T entity, CancellationToken cancellationToken = default)
78
- {
79
- _dbSet.Remove(entity);
80
- return Task.CompletedTask;
81
- }
82
-
83
- public IEnumerable<T> ExecuteQuery(string query, DbParameter[] dbParams)
84
- {
85
- return _dbSet
86
- .FromSqlRaw(query, dbParams)
87
- .AsNoTracking()
88
- .AsEnumerable();
89
- }
90
-
91
- public async Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default)
92
- {
93
- await _dbSet.AddRangeAsync(entities, cancellationToken);
94
- }
95
-
96
- public void RemoveRange(IEnumerable<T> entities)
97
- {
98
- _dbSet.RemoveRange(entities);
99
- }
100
- }
101
-
102
- // ============================================================
103
- // UnitOfWork — EF Core transaction management
104
- // ============================================================
105
-
106
- public class UnitOfWork : IUnitOfWork
107
- {
108
- private readonly ApplicationDbContext _dataContext;
109
-
110
- public UnitOfWork(ApplicationDbContext dataContext)
111
- {
112
- _dataContext = dataContext;
113
- }
114
-
115
- public int Commit()
116
- {
117
- return _dataContext.SaveChanges();
118
- }
119
-
120
- public async Task<int> CommitAsync(CancellationToken cancellationToken = default)
121
- {
122
- return await _dataContext.SaveChangesAsync(cancellationToken);
123
- }
124
-
125
- public void Rollback()
126
- {
127
- _dataContext.Dispose();
128
- }
129
-
130
- public async Task RollbackAsync()
131
- {
132
- await _dataContext.DisposeAsync();
133
- }
134
- }
135
-
136
- // ============================================================
137
- // DI REGISTRATION
138
- // ============================================================
139
- //
140
- // In Program.cs or a DI extension method:
141
- //
142
- // builder.Services.AddDbContext<ApplicationDbContext>(options =>
143
- // options.UseSqlServer(connectionString));
144
- //
145
- // builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
146
- // builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
147
- //
148
- // ============================================================
1
+ // ============================================================
2
+ // REPOSITORY + UNIT OF WORK TEMPLATE (VSA Pattern)
3
+ // Generated by MORPH Framework
4
+ // ============================================================
5
+
6
+ using System.Data.Common;
7
+ using Microsoft.EntityFrameworkCore;
8
+ using {{pascalCase PROJECT_NAME}}.Database;
9
+
10
+ namespace {{pascalCase PROJECT_NAME}}.Repository;
11
+
12
+ // ============================================================
13
+ // IRepository<T> — Generic repository contract
14
+ // ============================================================
15
+
16
+ public interface IRepository<T> where T : class
17
+ {
18
+ Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default);
19
+ Task<T?> GetByIdAsync(object id, CancellationToken cancellationToken = default);
20
+ Task<T> AddAsync(T entity, CancellationToken cancellationToken = default);
21
+ Task UpdateAsync(T entity, CancellationToken cancellationToken = default);
22
+ Task DeleteAsync(T entity, CancellationToken cancellationToken = default);
23
+ IEnumerable<T> ExecuteQuery(string query, DbParameter[] dbParams);
24
+ Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default);
25
+ void RemoveRange(IEnumerable<T> entities);
26
+ }
27
+
28
+ // ============================================================
29
+ // IUnitOfWork — Transaction boundary contract
30
+ // ============================================================
31
+
32
+ public interface IUnitOfWork
33
+ {
34
+ int Commit();
35
+ void Rollback();
36
+ Task<int> CommitAsync(CancellationToken cancellationToken = default);
37
+ Task RollbackAsync(CancellationToken cancellationToken = default);
38
+ }
39
+
40
+ // ============================================================
41
+ // Repository<T> — EF Core generic repository implementation
42
+ // ============================================================
43
+
44
+ public class Repository<T> : IRepository<T> where T : class
45
+ {
46
+ private readonly ApplicationDbContext _context;
47
+ private readonly DbSet<T> _dbSet;
48
+
49
+ public Repository(ApplicationDbContext context)
50
+ {
51
+ _context = context;
52
+ _dbSet = _context.Set<T>();
53
+ }
54
+
55
+ public async Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default)
56
+ {
57
+ return await _dbSet.ToListAsync(cancellationToken);
58
+ }
59
+
60
+ public async Task<T?> GetByIdAsync(object id, CancellationToken cancellationToken = default)
61
+ {
62
+ return await _dbSet.FindAsync(new[] { id }, cancellationToken);
63
+ }
64
+
65
+ public async Task<T> AddAsync(T entity, CancellationToken cancellationToken = default)
66
+ {
67
+ await _dbSet.AddAsync(entity, cancellationToken);
68
+ return entity;
69
+ }
70
+
71
+ public Task UpdateAsync(T entity, CancellationToken cancellationToken = default)
72
+ {
73
+ _dbSet.Update(entity);
74
+ return Task.CompletedTask;
75
+ }
76
+
77
+ public Task DeleteAsync(T entity, CancellationToken cancellationToken = default)
78
+ {
79
+ _dbSet.Remove(entity);
80
+ return Task.CompletedTask;
81
+ }
82
+
83
+ public IEnumerable<T> ExecuteQuery(string query, DbParameter[] dbParams)
84
+ {
85
+ return _dbSet
86
+ .FromSqlRaw(query, dbParams)
87
+ .AsNoTracking()
88
+ .AsEnumerable();
89
+ }
90
+
91
+ public async Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default)
92
+ {
93
+ await _dbSet.AddRangeAsync(entities, cancellationToken);
94
+ }
95
+
96
+ public void RemoveRange(IEnumerable<T> entities)
97
+ {
98
+ _dbSet.RemoveRange(entities);
99
+ }
100
+ }
101
+
102
+ // ============================================================
103
+ // UnitOfWork — EF Core transaction management
104
+ // ============================================================
105
+
106
+ public class UnitOfWork : IUnitOfWork
107
+ {
108
+ private readonly ApplicationDbContext _dataContext;
109
+
110
+ public UnitOfWork(ApplicationDbContext dataContext)
111
+ {
112
+ _dataContext = dataContext;
113
+ }
114
+
115
+ public int Commit()
116
+ {
117
+ return _dataContext.SaveChanges();
118
+ }
119
+
120
+ public async Task<int> CommitAsync(CancellationToken cancellationToken = default)
121
+ {
122
+ return await _dataContext.SaveChangesAsync(cancellationToken);
123
+ }
124
+
125
+ public void Rollback()
126
+ {
127
+ _dataContext.Dispose();
128
+ }
129
+
130
+ public async Task RollbackAsync(CancellationToken cancellationToken = default)
131
+ {
132
+ await _dataContext.DisposeAsync();
133
+ }
134
+ }
135
+
136
+ // ============================================================
137
+ // DI REGISTRATION
138
+ // ============================================================
139
+ //
140
+ // In Program.cs or a DI extension method:
141
+ //
142
+ // builder.Services.AddDbContext<ApplicationDbContext>(options =>
143
+ // options.UseSqlServer(connectionString));
144
+ //
145
+ // builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
146
+ // builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
147
+ //
148
+ // ============================================================
@@ -34,7 +34,7 @@ namespace {{NAMESPACE}}.Abstractions
34
34
  {
35
35
  public interface IApiEndpoint
36
36
  {
37
- void MapEndpoint(WebApplication app);
37
+ void MapEndpoint(IEndpointRouteBuilder app);
38
38
  }
39
39
  }
40
40
 
@@ -235,7 +235,7 @@ using {{NAMESPACE}}.Extensions;
235
235
 
236
236
  internal sealed class Create{{pascalCase FEATURE_NAME}}Endpoint : IApiEndpoint
237
237
  {
238
- public void MapEndpoint(WebApplication app)
238
+ public void MapEndpoint(IEndpointRouteBuilder app)
239
239
  {
240
240
  app.MapPost("{{ROUTE}}", async (
241
241
  IHandler<Create{{pascalCase FEATURE_NAME}}Request, Result<Create{{pascalCase FEATURE_NAME}}Response>> handler,
@@ -0,0 +1,93 @@
1
+ // ============================================================
2
+ // PGVECTOR ENTITY + CONFIGURATION TEMPLATE
3
+ // Generated by MORPH Framework
4
+ // ============================================================
5
+
6
+ using System.ComponentModel.DataAnnotations.Schema;
7
+ using Microsoft.EntityFrameworkCore;
8
+ using Microsoft.EntityFrameworkCore.Metadata.Builders;
9
+ using Pgvector;
10
+
11
+ #nullable disable
12
+
13
+ namespace {{NAMESPACE}}.Domain.Entities;
14
+
15
+ /// <summary>
16
+ /// Entity with vector embedding for similarity search via pgvector.
17
+ /// Dimensions: 1536 (text-embedding-3-small). Adjust if using a different model.
18
+ /// </summary>
19
+ public class {{pascalCase FEATURE_NAME}}
20
+ {
21
+ public Guid Id { get; set; }
22
+ public string Title { get; set; } = string.Empty;
23
+ public string Content { get; set; } = string.Empty;
24
+ public string? Metadata { get; set; }
25
+
26
+ [Column(TypeName = "vector(1536)")]
27
+ public Vector? Embedding { get; set; }
28
+
29
+ public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
30
+ public DateTimeOffset? UpdatedAt { get; set; }
31
+ }
32
+
33
+ // ============================================================
34
+ // ENTITY TYPE CONFIGURATION
35
+ // ============================================================
36
+
37
+ namespace {{NAMESPACE}}.Infrastructure.Data.Configurations;
38
+
39
+ public class {{pascalCase FEATURE_NAME}}Configuration : IEntityTypeConfiguration<{{pascalCase FEATURE_NAME}}>
40
+ {
41
+ public void Configure(EntityTypeBuilder<{{pascalCase FEATURE_NAME}}> builder)
42
+ {
43
+ builder.ToTable("{{snakeCase FEATURE_NAME}}s");
44
+ builder.HasKey(e => e.Id);
45
+ builder.Property(e => e.Id).HasDefaultValueSql("gen_random_uuid()");
46
+ builder.Property(e => e.Title).IsRequired().HasMaxLength(200);
47
+ builder.Property(e => e.Content).IsRequired();
48
+ builder.Property(e => e.Metadata).HasColumnType("jsonb");
49
+ builder.Property(e => e.Embedding).HasColumnType("vector(1536)");
50
+ builder.Property(e => e.CreatedAt).HasDefaultValueSql("now()");
51
+
52
+ // HNSW index for cosine similarity search
53
+ builder.HasIndex(e => e.Embedding)
54
+ .HasMethod("hnsw")
55
+ .HasOperators("vector_cosine_ops")
56
+ .HasStorageParameter("m", 16)
57
+ .HasStorageParameter("ef_construction", 64);
58
+
59
+ builder.HasIndex(e => e.Title);
60
+ }
61
+ }
62
+
63
+ // ============================================================
64
+ // SETUP INSTRUCTIONS
65
+ // ============================================================
66
+ //
67
+ // 1. Install NuGet packages:
68
+ //
69
+ // dotnet add package Pgvector.EntityFrameworkCore
70
+ // dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
71
+ //
72
+ // 2. Configure NpgsqlDataSource with vector support in Program.cs:
73
+ //
74
+ // builder.Services.AddNpgsql<AppDbContext>(
75
+ // connectionString,
76
+ // npgsqlOptions => npgsqlOptions.UseVector());
77
+ //
78
+ // 3. Register in DbContext:
79
+ //
80
+ // public DbSet<{{pascalCase FEATURE_NAME}}> {{pascalCase FEATURE_NAME}}s => Set<{{pascalCase FEATURE_NAME}}>();
81
+ //
82
+ // protected override void OnModelCreating(ModelBuilder modelBuilder)
83
+ // {
84
+ // modelBuilder.HasPostgresExtension("vector");
85
+ // modelBuilder.ApplyConfiguration(new {{pascalCase FEATURE_NAME}}Configuration());
86
+ // }
87
+ //
88
+ // 4. Create and apply migration:
89
+ //
90
+ // dotnet ef migrations add Add{{pascalCase FEATURE_NAME}}WithVector -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
91
+ // dotnet ef database update -p src/{{NAMESPACE}}.Infrastructure -s src/{{NAMESPACE}}.Web
92
+ //
93
+ // ============================================================
@@ -5,7 +5,7 @@ namespace {{pascalCase PROJECT_NAME}}.Features.{{pascalCase FEATURE_NAME}}Featur
5
5
 
6
6
  internal sealed class {{pascalCase SLICE_NAME}}Endpoint : IApiEndpoint
7
7
  {
8
- public void MapEndpoint(WebApplication app)
8
+ public void MapEndpoint(IEndpointRouteBuilder app)
9
9
  {
10
10
  app.MapPost("{{kebabCase FEATURE_NAME}}s", async (IHandler<{{pascalCase SLICE_NAME}}Request, Result<{{pascalCase SLICE_NAME}}Response>> handler, {{pascalCase SLICE_NAME}}Request command, CancellationToken cancellationToken) =>
11
11
  {
@@ -1,9 +1,8 @@
1
1
  -- ============================================================
2
2
  -- Migration: {{titleCase FEATURE_NAME}}
3
- -- Stack: Next.js + Supabase
3
+ -- Stack: Next.js + Neon
4
4
  -- Generated by MORPH Framework
5
5
  -- Date: {{DATE}}
6
- -- Run: supabase db push
7
6
  -- ============================================================
8
7
 
9
8
  -- ============================================================
@@ -12,7 +11,7 @@
12
11
 
13
12
  create table if not exists public.{{TABLE_NAME}} (
14
13
  id uuid primary key default gen_random_uuid(),
15
- user_id uuid not null references auth.users(id) on delete cascade,
14
+ user_id text not null,
16
15
  name text not null,
17
16
  status text not null default 'draft'
18
17
  check (status in ('draft', 'active', 'completed', 'archived', 'failed', 'cancelled')),
@@ -66,35 +65,27 @@ create trigger set_{{TABLE_NAME}}_updated_at
66
65
  -- Enable RLS
67
66
  alter table public.{{TABLE_NAME}} enable row level security;
68
67
 
69
- -- Users can read their own rows
68
+ -- Users can read their own rows (Neon Auth JWT via pg_session_jwt)
70
69
  create policy "Users can read own {{TABLE_NAME}}"
71
70
  on public.{{TABLE_NAME}}
72
- for select
73
- using (auth.uid() = user_id);
71
+ for select to authenticated
72
+ using (auth.user_id() = user_id);
74
73
 
75
74
  -- Users can insert rows for themselves
76
75
  create policy "Users can insert own {{TABLE_NAME}}"
77
76
  on public.{{TABLE_NAME}}
78
- for insert
79
- with check (auth.uid() = user_id);
77
+ for insert to authenticated
78
+ with check (auth.user_id() = user_id);
80
79
 
81
80
  -- Users can update their own rows
82
81
  create policy "Users can update own {{TABLE_NAME}}"
83
82
  on public.{{TABLE_NAME}}
84
- for update
85
- using (auth.uid() = user_id)
86
- with check (auth.uid() = user_id);
83
+ for update to authenticated
84
+ using (auth.user_id() = user_id)
85
+ with check (auth.user_id() = user_id);
87
86
 
88
87
  -- Users can delete their own rows
89
88
  create policy "Users can delete own {{TABLE_NAME}}"
90
89
  on public.{{TABLE_NAME}}
91
- for delete
92
- using (auth.uid() = user_id);
93
-
94
- -- ============================================================
95
- -- 5. GRANTS
96
- -- ============================================================
97
-
98
- -- Grant access to authenticated users (via Supabase API)
99
- grant select, insert, update, delete on public.{{TABLE_NAME}} to authenticated;
100
- grant usage on schema public to authenticated;
90
+ for delete to authenticated
91
+ using (auth.user_id() = user_id);
@@ -19,7 +19,7 @@ create table if not exists public.{{TABLE_NAME}} (
19
19
  is_active boolean default true not null,
20
20
 
21
21
  -- Foreign keys (example)
22
- -- user_id uuid references auth.users(id) on delete cascade,
22
+ -- user_id text not null,
23
23
 
24
24
  -- Timestamps
25
25
  created_at timestamptz default now() not null,
@@ -70,31 +70,26 @@ create policy "{{TABLE_NAME}}_select_policy"
70
70
  on public.{{TABLE_NAME}} for select
71
71
  using (true);
72
72
 
73
- -- Policy: Users can only insert their own records (example)
73
+ -- Policy: Users can only insert their own records (Neon Auth + pg_session_jwt)
74
74
  -- create policy "{{TABLE_NAME}}_insert_policy"
75
- -- on public.{{TABLE_NAME}} for insert
76
- -- with check (auth.uid() = user_id);
75
+ -- on public.{{TABLE_NAME}} for insert to authenticated
76
+ -- with check (auth.user_id() = user_id);
77
77
 
78
- -- Policy: Users can only update their own records (example)
78
+ -- Policy: Users can only update their own records (Neon Auth + pg_session_jwt)
79
79
  -- create policy "{{TABLE_NAME}}_update_policy"
80
- -- on public.{{TABLE_NAME}} for update
81
- -- using (auth.uid() = user_id)
82
- -- with check (auth.uid() = user_id);
80
+ -- on public.{{TABLE_NAME}} for update to authenticated
81
+ -- using (auth.user_id() = user_id)
82
+ -- with check (auth.user_id() = user_id);
83
83
 
84
- -- Policy: Users can only delete their own records (example)
84
+ -- Policy: Users can only delete their own records (Neon Auth + pg_session_jwt)
85
85
  -- create policy "{{TABLE_NAME}}_delete_policy"
86
- -- on public.{{TABLE_NAME}} for delete
87
- -- using (auth.uid() = user_id);
86
+ -- on public.{{TABLE_NAME}} for delete to authenticated
87
+ -- using (auth.user_id() = user_id);
88
88
 
89
- -- Policy: Admins have full access (example)
89
+ -- Policy: Admins have full access (Neon Auth + pg_session_jwt)
90
90
  -- create policy "{{TABLE_NAME}}_admin_policy"
91
91
  -- on public.{{TABLE_NAME}} for all
92
- -- using (
93
- -- exists (
94
- -- select 1 from public.user_roles
95
- -- where user_id = auth.uid() and role = 'admin'
96
- -- )
97
- -- );
92
+ -- using (auth.jwt()->>'role' = 'admin');
98
93
 
99
94
  -- ========================================
100
95
  -- Seed Data (Optional)
@@ -1,6 +1,6 @@
1
1
  -- ============================================================
2
2
  -- RLS Policy: {{titleCase FEATURE_NAME}}
3
- -- Stack: Next.js + Supabase
3
+ -- Stack: Next.js + Neon
4
4
  -- Generated by MORPH Framework
5
5
  -- Date: {{DATE}}
6
6
  -- ============================================================
@@ -40,18 +40,15 @@ create policy "{{POLICY_NAME}}_delete"
40
40
  using ({{USING_EXPRESSION}});
41
41
 
42
42
  -- ============================================================
43
- -- Common USING / WITH CHECK expressions:
43
+ -- Common USING / WITH CHECK expressions (Neon Auth + pg_session_jwt):
44
44
  --
45
45
  -- Owner-based:
46
- -- auth.uid() = user_id
46
+ -- auth.user_id() = user_id
47
47
  --
48
- -- Role-based:
49
- -- auth.jwt() ->> 'role' = 'admin'
50
- --
51
- -- Organization-based:
52
- -- org_id in (select org_id from public.org_members where user_id = auth.uid())
48
+ -- Role-based (extract from JWT claims):
49
+ -- auth.jwt()->>'role' = 'admin'
53
50
  --
54
51
  -- Public read, owner write:
55
52
  -- SELECT using (true)
56
- -- INSERT/UPDATE/DELETE using (auth.uid() = user_id)
53
+ -- INSERT/UPDATE/DELETE using (auth.user_id() = user_id)
57
54
  -- ============================================================