@nuxt-customer-portal/core 0.3.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 (66) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +21 -0
  3. package/README.md +35 -0
  4. package/app/composables/useAutoPagination.ts +30 -0
  5. package/app/composables/useOrganization.ts +117 -0
  6. package/app/composables/usePaginatedResource.ts +167 -0
  7. package/app/composables/usePortalFeatures.ts +74 -0
  8. package/app/composables/usePortalSession.ts +20 -0
  9. package/app/composables/useUserStore.ts +460 -0
  10. package/app/middleware/auth.global.ts +32 -0
  11. package/app/plugins/auth.ts +28 -0
  12. package/app/plugins/portal-core-feature.ts +3 -0
  13. package/app/types/index.d.ts +75 -0
  14. package/app/utils/auth-client.ts +31 -0
  15. package/app/utils/permission-utils.ts +21 -0
  16. package/app/utils/random.ts +9 -0
  17. package/i18n/locales/en.json +81 -0
  18. package/i18n/locales/nl.json +81 -0
  19. package/migrations/0000_baseline.sql +119 -0
  20. package/migrations/0001_organization_types.sql +12 -0
  21. package/migrations/0002_invitation_created_at.sql +1 -0
  22. package/migrations/0003_system_admin_role.sql +5 -0
  23. package/migrations/0004_provider_organization_type.sql +16 -0
  24. package/migrations/0005_portal_email_settings.sql +15 -0
  25. package/migrations/meta/0000_snapshot.json +880 -0
  26. package/migrations/meta/_journal.json +13 -0
  27. package/nuxt.config.ts +55 -0
  28. package/package.json +66 -0
  29. package/portal.manifest.mjs +8 -0
  30. package/server/api/auth/[...].ts +18 -0
  31. package/server/api/auth/permissions.get.ts +64 -0
  32. package/server/api/notifications.ts +294 -0
  33. package/server/db/core-schema.ts +1 -0
  34. package/server/db/schema/auth-schema.ts +198 -0
  35. package/server/db/schema/index.ts +1 -0
  36. package/server/middleware/api-docs-auth.ts +26 -0
  37. package/server/middleware/auth.ts +61 -0
  38. package/server/portal.ts +212 -0
  39. package/server/routes/api-docs/openapi.json.get.ts +22 -0
  40. package/server/utils/admin-email-allowlist.ts +12 -0
  41. package/server/utils/auth.ts +326 -0
  42. package/server/utils/business-hooks.ts +28 -0
  43. package/server/utils/db.ts +18 -0
  44. package/server/utils/email-template.html +105 -0
  45. package/server/utils/email-texts.ts +110 -0
  46. package/server/utils/email.ts +37 -0
  47. package/server/utils/invitation-management.ts +29 -0
  48. package/server/utils/openapi-auth.ts +67 -0
  49. package/server/utils/openapi-contracts.ts +129 -0
  50. package/server/utils/openapi-order.ts +136 -0
  51. package/server/utils/permissions.ts +179 -0
  52. package/server/utils/portal-email.ts +424 -0
  53. package/server/utils/query-builder.ts +270 -0
  54. package/server/utils/route-meta.ts +28 -0
  55. package/shared/core-feature.ts +152 -0
  56. package/shared/feature-registry.ts +62 -0
  57. package/shared/invitation-validation.ts +8 -0
  58. package/shared/organization-avatar.ts +11 -0
  59. package/shared/permissions.ts +26 -0
  60. package/shared/portal-session.ts +17 -0
  61. package/shared/types/feature.ts +130 -0
  62. package/shared/types/index.ts +40 -0
  63. package/shared/types/sections/api.ts +134 -0
  64. package/shared/types/sections/auth.ts +71 -0
  65. package/shared/types/sections/database.ts +86 -0
  66. package/shared/types/sections/queryBuilder.ts +31 -0
@@ -0,0 +1,880 @@
1
+ {
2
+ "id": "5d02cdeb-5b21-4b31-be63-c05d2043391f",
3
+ "prevId": "00000000-0000-0000-0000-000000000000",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.account": {
8
+ "name": "account",
9
+ "schema": "",
10
+ "columns": {
11
+ "id": {
12
+ "name": "id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "account_id": {
18
+ "name": "account_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true
22
+ },
23
+ "provider_id": {
24
+ "name": "provider_id",
25
+ "type": "text",
26
+ "primaryKey": false,
27
+ "notNull": true
28
+ },
29
+ "user_id": {
30
+ "name": "user_id",
31
+ "type": "text",
32
+ "primaryKey": false,
33
+ "notNull": true
34
+ },
35
+ "access_token": {
36
+ "name": "access_token",
37
+ "type": "text",
38
+ "primaryKey": false,
39
+ "notNull": false
40
+ },
41
+ "refresh_token": {
42
+ "name": "refresh_token",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": false
46
+ },
47
+ "id_token": {
48
+ "name": "id_token",
49
+ "type": "text",
50
+ "primaryKey": false,
51
+ "notNull": false
52
+ },
53
+ "access_token_expires_at": {
54
+ "name": "access_token_expires_at",
55
+ "type": "timestamp",
56
+ "primaryKey": false,
57
+ "notNull": false
58
+ },
59
+ "refresh_token_expires_at": {
60
+ "name": "refresh_token_expires_at",
61
+ "type": "timestamp",
62
+ "primaryKey": false,
63
+ "notNull": false
64
+ },
65
+ "scope": {
66
+ "name": "scope",
67
+ "type": "text",
68
+ "primaryKey": false,
69
+ "notNull": false
70
+ },
71
+ "password": {
72
+ "name": "password",
73
+ "type": "text",
74
+ "primaryKey": false,
75
+ "notNull": false
76
+ },
77
+ "created_at": {
78
+ "name": "created_at",
79
+ "type": "timestamp",
80
+ "primaryKey": false,
81
+ "notNull": true,
82
+ "default": "now()"
83
+ },
84
+ "updated_at": {
85
+ "name": "updated_at",
86
+ "type": "timestamp",
87
+ "primaryKey": false,
88
+ "notNull": true
89
+ }
90
+ },
91
+ "indexes": {
92
+ "account_user_id_idx": {
93
+ "name": "account_user_id_idx",
94
+ "columns": [
95
+ {
96
+ "expression": "user_id",
97
+ "isExpression": false,
98
+ "asc": true,
99
+ "nulls": "last"
100
+ }
101
+ ],
102
+ "isUnique": false,
103
+ "concurrently": false,
104
+ "method": "btree",
105
+ "with": {}
106
+ },
107
+ "account_account_id_idx": {
108
+ "name": "account_account_id_idx",
109
+ "columns": [
110
+ {
111
+ "expression": "account_id",
112
+ "isExpression": false,
113
+ "asc": true,
114
+ "nulls": "last"
115
+ }
116
+ ],
117
+ "isUnique": false,
118
+ "concurrently": false,
119
+ "method": "btree",
120
+ "with": {}
121
+ },
122
+ "account_provider_id_idx": {
123
+ "name": "account_provider_id_idx",
124
+ "columns": [
125
+ {
126
+ "expression": "provider_id",
127
+ "isExpression": false,
128
+ "asc": true,
129
+ "nulls": "last"
130
+ }
131
+ ],
132
+ "isUnique": false,
133
+ "concurrently": false,
134
+ "method": "btree",
135
+ "with": {}
136
+ }
137
+ },
138
+ "foreignKeys": {
139
+ "account_user_id_user_id_fk": {
140
+ "name": "account_user_id_user_id_fk",
141
+ "tableFrom": "account",
142
+ "tableTo": "user",
143
+ "columnsFrom": ["user_id"],
144
+ "columnsTo": ["id"],
145
+ "onDelete": "cascade",
146
+ "onUpdate": "no action"
147
+ }
148
+ },
149
+ "compositePrimaryKeys": {},
150
+ "uniqueConstraints": {},
151
+ "policies": {},
152
+ "checkConstraints": {},
153
+ "isRLSEnabled": false
154
+ },
155
+ "public.invitation": {
156
+ "name": "invitation",
157
+ "schema": "",
158
+ "columns": {
159
+ "id": {
160
+ "name": "id",
161
+ "type": "text",
162
+ "primaryKey": true,
163
+ "notNull": true
164
+ },
165
+ "organization_id": {
166
+ "name": "organization_id",
167
+ "type": "text",
168
+ "primaryKey": false,
169
+ "notNull": true
170
+ },
171
+ "email": {
172
+ "name": "email",
173
+ "type": "text",
174
+ "primaryKey": false,
175
+ "notNull": true
176
+ },
177
+ "role": {
178
+ "name": "role",
179
+ "type": "text",
180
+ "primaryKey": false,
181
+ "notNull": false
182
+ },
183
+ "status": {
184
+ "name": "status",
185
+ "type": "text",
186
+ "primaryKey": false,
187
+ "notNull": true,
188
+ "default": "'pending'"
189
+ },
190
+ "expires_at": {
191
+ "name": "expires_at",
192
+ "type": "timestamp",
193
+ "primaryKey": false,
194
+ "notNull": true
195
+ },
196
+ "inviter_id": {
197
+ "name": "inviter_id",
198
+ "type": "text",
199
+ "primaryKey": false,
200
+ "notNull": true
201
+ }
202
+ },
203
+ "indexes": {
204
+ "invitation_organization_id_idx": {
205
+ "name": "invitation_organization_id_idx",
206
+ "columns": [
207
+ {
208
+ "expression": "organization_id",
209
+ "isExpression": false,
210
+ "asc": true,
211
+ "nulls": "last"
212
+ }
213
+ ],
214
+ "isUnique": false,
215
+ "concurrently": false,
216
+ "method": "btree",
217
+ "with": {}
218
+ },
219
+ "invitation_inviter_id_idx": {
220
+ "name": "invitation_inviter_id_idx",
221
+ "columns": [
222
+ {
223
+ "expression": "inviter_id",
224
+ "isExpression": false,
225
+ "asc": true,
226
+ "nulls": "last"
227
+ }
228
+ ],
229
+ "isUnique": false,
230
+ "concurrently": false,
231
+ "method": "btree",
232
+ "with": {}
233
+ },
234
+ "invitation_email_idx": {
235
+ "name": "invitation_email_idx",
236
+ "columns": [
237
+ {
238
+ "expression": "email",
239
+ "isExpression": false,
240
+ "asc": true,
241
+ "nulls": "last"
242
+ }
243
+ ],
244
+ "isUnique": false,
245
+ "concurrently": false,
246
+ "method": "btree",
247
+ "with": {}
248
+ }
249
+ },
250
+ "foreignKeys": {
251
+ "invitation_organization_id_organization_id_fk": {
252
+ "name": "invitation_organization_id_organization_id_fk",
253
+ "tableFrom": "invitation",
254
+ "tableTo": "organization",
255
+ "columnsFrom": ["organization_id"],
256
+ "columnsTo": ["id"],
257
+ "onDelete": "cascade",
258
+ "onUpdate": "no action"
259
+ },
260
+ "invitation_inviter_id_user_id_fk": {
261
+ "name": "invitation_inviter_id_user_id_fk",
262
+ "tableFrom": "invitation",
263
+ "tableTo": "user",
264
+ "columnsFrom": ["inviter_id"],
265
+ "columnsTo": ["id"],
266
+ "onDelete": "cascade",
267
+ "onUpdate": "no action"
268
+ }
269
+ },
270
+ "compositePrimaryKeys": {},
271
+ "uniqueConstraints": {},
272
+ "policies": {},
273
+ "checkConstraints": {},
274
+ "isRLSEnabled": false
275
+ },
276
+ "public.member": {
277
+ "name": "member",
278
+ "schema": "",
279
+ "columns": {
280
+ "id": {
281
+ "name": "id",
282
+ "type": "text",
283
+ "primaryKey": true,
284
+ "notNull": true
285
+ },
286
+ "organization_id": {
287
+ "name": "organization_id",
288
+ "type": "text",
289
+ "primaryKey": false,
290
+ "notNull": true
291
+ },
292
+ "user_id": {
293
+ "name": "user_id",
294
+ "type": "text",
295
+ "primaryKey": false,
296
+ "notNull": true
297
+ },
298
+ "role": {
299
+ "name": "role",
300
+ "type": "text",
301
+ "primaryKey": false,
302
+ "notNull": true,
303
+ "default": "'member'"
304
+ },
305
+ "created_at": {
306
+ "name": "created_at",
307
+ "type": "timestamp",
308
+ "primaryKey": false,
309
+ "notNull": true
310
+ }
311
+ },
312
+ "indexes": {
313
+ "member_organization_id_idx": {
314
+ "name": "member_organization_id_idx",
315
+ "columns": [
316
+ {
317
+ "expression": "organization_id",
318
+ "isExpression": false,
319
+ "asc": true,
320
+ "nulls": "last"
321
+ }
322
+ ],
323
+ "isUnique": false,
324
+ "concurrently": false,
325
+ "method": "btree",
326
+ "with": {}
327
+ },
328
+ "member_user_id_idx": {
329
+ "name": "member_user_id_idx",
330
+ "columns": [
331
+ {
332
+ "expression": "user_id",
333
+ "isExpression": false,
334
+ "asc": true,
335
+ "nulls": "last"
336
+ }
337
+ ],
338
+ "isUnique": false,
339
+ "concurrently": false,
340
+ "method": "btree",
341
+ "with": {}
342
+ }
343
+ },
344
+ "foreignKeys": {
345
+ "member_organization_id_organization_id_fk": {
346
+ "name": "member_organization_id_organization_id_fk",
347
+ "tableFrom": "member",
348
+ "tableTo": "organization",
349
+ "columnsFrom": ["organization_id"],
350
+ "columnsTo": ["id"],
351
+ "onDelete": "cascade",
352
+ "onUpdate": "no action"
353
+ },
354
+ "member_user_id_user_id_fk": {
355
+ "name": "member_user_id_user_id_fk",
356
+ "tableFrom": "member",
357
+ "tableTo": "user",
358
+ "columnsFrom": ["user_id"],
359
+ "columnsTo": ["id"],
360
+ "onDelete": "cascade",
361
+ "onUpdate": "no action"
362
+ }
363
+ },
364
+ "compositePrimaryKeys": {},
365
+ "uniqueConstraints": {},
366
+ "policies": {},
367
+ "checkConstraints": {},
368
+ "isRLSEnabled": false
369
+ },
370
+ "public.organization": {
371
+ "name": "organization",
372
+ "schema": "",
373
+ "columns": {
374
+ "id": {
375
+ "name": "id",
376
+ "type": "text",
377
+ "primaryKey": true,
378
+ "notNull": true
379
+ },
380
+ "name": {
381
+ "name": "name",
382
+ "type": "text",
383
+ "primaryKey": false,
384
+ "notNull": true
385
+ },
386
+ "slug": {
387
+ "name": "slug",
388
+ "type": "text",
389
+ "primaryKey": false,
390
+ "notNull": true
391
+ },
392
+ "logo": {
393
+ "name": "logo",
394
+ "type": "text",
395
+ "primaryKey": false,
396
+ "notNull": false
397
+ },
398
+ "created_at": {
399
+ "name": "created_at",
400
+ "type": "timestamp",
401
+ "primaryKey": false,
402
+ "notNull": true
403
+ },
404
+ "metadata": {
405
+ "name": "metadata",
406
+ "type": "text",
407
+ "primaryKey": false,
408
+ "notNull": false
409
+ }
410
+ },
411
+ "indexes": {
412
+ "organization_slug_idx": {
413
+ "name": "organization_slug_idx",
414
+ "columns": [
415
+ {
416
+ "expression": "slug",
417
+ "isExpression": false,
418
+ "asc": true,
419
+ "nulls": "last"
420
+ }
421
+ ],
422
+ "isUnique": false,
423
+ "concurrently": false,
424
+ "method": "btree",
425
+ "with": {}
426
+ }
427
+ },
428
+ "foreignKeys": {},
429
+ "compositePrimaryKeys": {},
430
+ "uniqueConstraints": {
431
+ "organization_slug_unique": {
432
+ "name": "organization_slug_unique",
433
+ "nullsNotDistinct": false,
434
+ "columns": ["slug"]
435
+ }
436
+ },
437
+ "policies": {},
438
+ "checkConstraints": {},
439
+ "isRLSEnabled": false
440
+ },
441
+ "public.organization_email_credential": {
442
+ "name": "organization_email_credential",
443
+ "schema": "",
444
+ "columns": {
445
+ "organization_id": {
446
+ "name": "organization_id",
447
+ "type": "text",
448
+ "primaryKey": true,
449
+ "notNull": true
450
+ },
451
+ "provider": {
452
+ "name": "provider",
453
+ "type": "text",
454
+ "primaryKey": false,
455
+ "notNull": true,
456
+ "default": "'RESEND'"
457
+ },
458
+ "api_key": {
459
+ "name": "api_key",
460
+ "type": "text",
461
+ "primaryKey": false,
462
+ "notNull": false
463
+ },
464
+ "key_fingerprint": {
465
+ "name": "key_fingerprint",
466
+ "type": "text",
467
+ "primaryKey": false,
468
+ "notNull": false
469
+ },
470
+ "key_last_four": {
471
+ "name": "key_last_four",
472
+ "type": "text",
473
+ "primaryKey": false,
474
+ "notNull": false
475
+ },
476
+ "configured_by_id": {
477
+ "name": "configured_by_id",
478
+ "type": "text",
479
+ "primaryKey": false,
480
+ "notNull": false
481
+ },
482
+ "removed_by_id": {
483
+ "name": "removed_by_id",
484
+ "type": "text",
485
+ "primaryKey": false,
486
+ "notNull": false
487
+ },
488
+ "removed_at": {
489
+ "name": "removed_at",
490
+ "type": "timestamp",
491
+ "primaryKey": false,
492
+ "notNull": false
493
+ },
494
+ "created_at": {
495
+ "name": "created_at",
496
+ "type": "timestamp",
497
+ "primaryKey": false,
498
+ "notNull": true,
499
+ "default": "now()"
500
+ },
501
+ "updated_at": {
502
+ "name": "updated_at",
503
+ "type": "timestamp",
504
+ "primaryKey": false,
505
+ "notNull": true,
506
+ "default": "now()"
507
+ }
508
+ },
509
+ "indexes": {},
510
+ "foreignKeys": {
511
+ "organization_email_credential_organization_id_organization_id_fk": {
512
+ "name": "organization_email_credential_organization_id_organization_id_fk",
513
+ "tableFrom": "organization_email_credential",
514
+ "tableTo": "organization",
515
+ "columnsFrom": ["organization_id"],
516
+ "columnsTo": ["id"],
517
+ "onDelete": "cascade",
518
+ "onUpdate": "no action"
519
+ },
520
+ "organization_email_credential_configured_by_id_user_id_fk": {
521
+ "name": "organization_email_credential_configured_by_id_user_id_fk",
522
+ "tableFrom": "organization_email_credential",
523
+ "tableTo": "user",
524
+ "columnsFrom": ["configured_by_id"],
525
+ "columnsTo": ["id"],
526
+ "onDelete": "set null",
527
+ "onUpdate": "no action"
528
+ },
529
+ "organization_email_credential_removed_by_id_user_id_fk": {
530
+ "name": "organization_email_credential_removed_by_id_user_id_fk",
531
+ "tableFrom": "organization_email_credential",
532
+ "tableTo": "user",
533
+ "columnsFrom": ["removed_by_id"],
534
+ "columnsTo": ["id"],
535
+ "onDelete": "set null",
536
+ "onUpdate": "no action"
537
+ }
538
+ },
539
+ "compositePrimaryKeys": {},
540
+ "uniqueConstraints": {},
541
+ "policies": {},
542
+ "checkConstraints": {},
543
+ "isRLSEnabled": false
544
+ },
545
+ "public.session": {
546
+ "name": "session",
547
+ "schema": "",
548
+ "columns": {
549
+ "id": {
550
+ "name": "id",
551
+ "type": "text",
552
+ "primaryKey": true,
553
+ "notNull": true
554
+ },
555
+ "expires_at": {
556
+ "name": "expires_at",
557
+ "type": "timestamp",
558
+ "primaryKey": false,
559
+ "notNull": true
560
+ },
561
+ "token": {
562
+ "name": "token",
563
+ "type": "text",
564
+ "primaryKey": false,
565
+ "notNull": true
566
+ },
567
+ "created_at": {
568
+ "name": "created_at",
569
+ "type": "timestamp",
570
+ "primaryKey": false,
571
+ "notNull": true,
572
+ "default": "now()"
573
+ },
574
+ "updated_at": {
575
+ "name": "updated_at",
576
+ "type": "timestamp",
577
+ "primaryKey": false,
578
+ "notNull": true
579
+ },
580
+ "ip_address": {
581
+ "name": "ip_address",
582
+ "type": "text",
583
+ "primaryKey": false,
584
+ "notNull": false
585
+ },
586
+ "user_agent": {
587
+ "name": "user_agent",
588
+ "type": "text",
589
+ "primaryKey": false,
590
+ "notNull": false
591
+ },
592
+ "user_id": {
593
+ "name": "user_id",
594
+ "type": "text",
595
+ "primaryKey": false,
596
+ "notNull": true
597
+ },
598
+ "active_organization_id": {
599
+ "name": "active_organization_id",
600
+ "type": "text",
601
+ "primaryKey": false,
602
+ "notNull": false
603
+ },
604
+ "impersonated_by": {
605
+ "name": "impersonated_by",
606
+ "type": "text",
607
+ "primaryKey": false,
608
+ "notNull": false
609
+ }
610
+ },
611
+ "indexes": {
612
+ "session_user_id_idx": {
613
+ "name": "session_user_id_idx",
614
+ "columns": [
615
+ {
616
+ "expression": "user_id",
617
+ "isExpression": false,
618
+ "asc": true,
619
+ "nulls": "last"
620
+ }
621
+ ],
622
+ "isUnique": false,
623
+ "concurrently": false,
624
+ "method": "btree",
625
+ "with": {}
626
+ },
627
+ "session_active_organization_id_idx": {
628
+ "name": "session_active_organization_id_idx",
629
+ "columns": [
630
+ {
631
+ "expression": "active_organization_id",
632
+ "isExpression": false,
633
+ "asc": true,
634
+ "nulls": "last"
635
+ }
636
+ ],
637
+ "isUnique": false,
638
+ "concurrently": false,
639
+ "method": "btree",
640
+ "with": {}
641
+ }
642
+ },
643
+ "foreignKeys": {
644
+ "session_user_id_user_id_fk": {
645
+ "name": "session_user_id_user_id_fk",
646
+ "tableFrom": "session",
647
+ "tableTo": "user",
648
+ "columnsFrom": ["user_id"],
649
+ "columnsTo": ["id"],
650
+ "onDelete": "cascade",
651
+ "onUpdate": "no action"
652
+ }
653
+ },
654
+ "compositePrimaryKeys": {},
655
+ "uniqueConstraints": {
656
+ "session_token_unique": {
657
+ "name": "session_token_unique",
658
+ "nullsNotDistinct": false,
659
+ "columns": ["token"]
660
+ }
661
+ },
662
+ "policies": {},
663
+ "checkConstraints": {},
664
+ "isRLSEnabled": false
665
+ },
666
+ "public.user": {
667
+ "name": "user",
668
+ "schema": "",
669
+ "columns": {
670
+ "id": {
671
+ "name": "id",
672
+ "type": "text",
673
+ "primaryKey": true,
674
+ "notNull": true
675
+ },
676
+ "name": {
677
+ "name": "name",
678
+ "type": "text",
679
+ "primaryKey": false,
680
+ "notNull": true
681
+ },
682
+ "email": {
683
+ "name": "email",
684
+ "type": "text",
685
+ "primaryKey": false,
686
+ "notNull": true
687
+ },
688
+ "email_verified": {
689
+ "name": "email_verified",
690
+ "type": "boolean",
691
+ "primaryKey": false,
692
+ "notNull": true,
693
+ "default": false
694
+ },
695
+ "image": {
696
+ "name": "image",
697
+ "type": "text",
698
+ "primaryKey": false,
699
+ "notNull": false
700
+ },
701
+ "created_at": {
702
+ "name": "created_at",
703
+ "type": "timestamp",
704
+ "primaryKey": false,
705
+ "notNull": true,
706
+ "default": "now()"
707
+ },
708
+ "updated_at": {
709
+ "name": "updated_at",
710
+ "type": "timestamp",
711
+ "primaryKey": false,
712
+ "notNull": true,
713
+ "default": "now()"
714
+ },
715
+ "role": {
716
+ "name": "role",
717
+ "type": "text",
718
+ "primaryKey": false,
719
+ "notNull": false
720
+ },
721
+ "banned": {
722
+ "name": "banned",
723
+ "type": "boolean",
724
+ "primaryKey": false,
725
+ "notNull": false,
726
+ "default": false
727
+ },
728
+ "ban_reason": {
729
+ "name": "ban_reason",
730
+ "type": "text",
731
+ "primaryKey": false,
732
+ "notNull": false
733
+ },
734
+ "ban_expires": {
735
+ "name": "ban_expires",
736
+ "type": "timestamp",
737
+ "primaryKey": false,
738
+ "notNull": false
739
+ }
740
+ },
741
+ "indexes": {
742
+ "user_name_idx": {
743
+ "name": "user_name_idx",
744
+ "columns": [
745
+ {
746
+ "expression": "name",
747
+ "isExpression": false,
748
+ "asc": true,
749
+ "nulls": "last"
750
+ }
751
+ ],
752
+ "isUnique": false,
753
+ "concurrently": false,
754
+ "method": "btree",
755
+ "with": {}
756
+ },
757
+ "user_email_idx": {
758
+ "name": "user_email_idx",
759
+ "columns": [
760
+ {
761
+ "expression": "email",
762
+ "isExpression": false,
763
+ "asc": true,
764
+ "nulls": "last"
765
+ }
766
+ ],
767
+ "isUnique": true,
768
+ "concurrently": false,
769
+ "method": "btree",
770
+ "with": {}
771
+ }
772
+ },
773
+ "foreignKeys": {},
774
+ "compositePrimaryKeys": {},
775
+ "uniqueConstraints": {
776
+ "user_email_unique": {
777
+ "name": "user_email_unique",
778
+ "nullsNotDistinct": false,
779
+ "columns": ["email"]
780
+ }
781
+ },
782
+ "policies": {},
783
+ "checkConstraints": {},
784
+ "isRLSEnabled": false
785
+ },
786
+ "public.verification": {
787
+ "name": "verification",
788
+ "schema": "",
789
+ "columns": {
790
+ "id": {
791
+ "name": "id",
792
+ "type": "text",
793
+ "primaryKey": true,
794
+ "notNull": true
795
+ },
796
+ "identifier": {
797
+ "name": "identifier",
798
+ "type": "text",
799
+ "primaryKey": false,
800
+ "notNull": true
801
+ },
802
+ "value": {
803
+ "name": "value",
804
+ "type": "text",
805
+ "primaryKey": false,
806
+ "notNull": true
807
+ },
808
+ "expires_at": {
809
+ "name": "expires_at",
810
+ "type": "timestamp",
811
+ "primaryKey": false,
812
+ "notNull": true
813
+ },
814
+ "created_at": {
815
+ "name": "created_at",
816
+ "type": "timestamp",
817
+ "primaryKey": false,
818
+ "notNull": true,
819
+ "default": "now()"
820
+ },
821
+ "updated_at": {
822
+ "name": "updated_at",
823
+ "type": "timestamp",
824
+ "primaryKey": false,
825
+ "notNull": true,
826
+ "default": "now()"
827
+ }
828
+ },
829
+ "indexes": {
830
+ "verification_identifier_idx": {
831
+ "name": "verification_identifier_idx",
832
+ "columns": [
833
+ {
834
+ "expression": "identifier",
835
+ "isExpression": false,
836
+ "asc": true,
837
+ "nulls": "last"
838
+ }
839
+ ],
840
+ "isUnique": false,
841
+ "concurrently": false,
842
+ "method": "btree",
843
+ "with": {}
844
+ },
845
+ "verification_value_idx": {
846
+ "name": "verification_value_idx",
847
+ "columns": [
848
+ {
849
+ "expression": "value",
850
+ "isExpression": false,
851
+ "asc": true,
852
+ "nulls": "last"
853
+ }
854
+ ],
855
+ "isUnique": false,
856
+ "concurrently": false,
857
+ "method": "btree",
858
+ "with": {}
859
+ }
860
+ },
861
+ "foreignKeys": {},
862
+ "compositePrimaryKeys": {},
863
+ "uniqueConstraints": {},
864
+ "policies": {},
865
+ "checkConstraints": {},
866
+ "isRLSEnabled": false
867
+ }
868
+ },
869
+ "enums": {},
870
+ "schemas": {},
871
+ "sequences": {},
872
+ "roles": {},
873
+ "policies": {},
874
+ "views": {},
875
+ "_meta": {
876
+ "columns": {},
877
+ "schemas": {},
878
+ "tables": {}
879
+ }
880
+ }