@trycompai/db 1.0.7 → 1.0.9

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 (127) hide show
  1. package/README.md +50 -20
  2. package/dist/index.d.mts +3 -8
  3. package/dist/index.d.ts +3 -8
  4. package/dist/index.js +3 -15
  5. package/dist/index.mjs +2 -13
  6. package/dist/prisma/schema.prisma +2 -2
  7. package/dist/setup.d.mts +7 -0
  8. package/dist/setup.d.ts +7 -0
  9. package/dist/setup.js +35 -0
  10. package/dist/setup.mjs +10 -0
  11. package/package.json +18 -9
  12. package/prisma/functionDefinition.sql +18 -0
  13. package/prisma/migrations/20250403163138_init/migration.sql +611 -0
  14. package/prisma/migrations/20250403165218_archived_on_its_own/migration.sql +29 -0
  15. package/prisma/migrations/20250403194504_risk_assignee/migration.sql +18 -0
  16. package/prisma/migrations/20250403201319_tasks_use_asignee/migration.sql +16 -0
  17. package/prisma/migrations/20250403205655_vendor_assignee/migration.sql +22 -0
  18. package/prisma/migrations/20250403205840_oops_optional/migration.sql +2 -0
  19. package/prisma/migrations/20250403210049_task_assignee_optional_too/migration.sql +8 -0
  20. package/prisma/migrations/20250404004853_stripecustomerid/migration.sql +2 -0
  21. package/prisma/migrations/20250406004306_added_common_comment_table/migration.sql +20 -0
  22. package/prisma/migrations/20250410193847_add_unique_constraint_to_artifact_t_table/migration.sql +30 -0
  23. package/prisma/migrations/20250410193857_remove_published_field_from_evidence/migration.sql +12 -0
  24. package/prisma/migrations/20250414191353_onboarding_experience/migration.sql +25 -0
  25. package/prisma/migrations/20250414203443_added_evidence_to_onboarding/migration.sql +2 -0
  26. package/prisma/migrations/20250417205622_add_global_vendors/migration.sql +26 -0
  27. package/prisma/migrations/20250417205625_update_task_table_and_comments_and_attachments/migration.sql +86 -0
  28. package/prisma/migrations/20250417205627_remove_evidence_table/migration.sql +109 -0
  29. package/prisma/migrations/20250417205629_frequency_task_is_optional/migration.sql +2 -0
  30. package/prisma/migrations/20250418151856_add_comment_relationship_to_attachment_and_vice_versa/migration.sql +8 -0
  31. package/prisma/migrations/20250423154259_make_role_string/migration.sql +9 -0
  32. package/prisma/migrations/20250424165055_update_onboarding_to_use_tasks/migration.sql +9 -0
  33. package/prisma/migrations/20250424170518_remove_evidence_artifact_type/migration.sql +14 -0
  34. package/prisma/migrations/20250428202144_add_website_to_organization/migration.sql +2 -0
  35. package/prisma/migrations/20250429155419_add_company_details_to_onboarding/migration.sql +2 -0
  36. package/prisma/migrations/20250509160401_added_framework_editor/migration.sql +8 -0
  37. package/prisma/migrations/20250509162708_init_framework_editor_tables/migration.sql +122 -0
  38. package/prisma/migrations/20250509172401_drop_slug/migration.sql +11 -0
  39. package/prisma/migrations/20250509232122_trust_portal/migration.sql +24 -0
  40. package/prisma/migrations/20250511040043_add_custom_domain_to_trust_portal/migration.sql +2 -0
  41. package/prisma/migrations/20250511042943_trust_portal_domain_verified/migration.sql +2 -0
  42. package/prisma/migrations/20250512004633_added_identifier/migration.sql +5 -0
  43. package/prisma/migrations/20250512115717_added_framework_status/migration.sql +7 -0
  44. package/prisma/migrations/20250512163351_add_contact_details_trust_portal/migration.sql +2 -0
  45. package/prisma/migrations/20250514143147_remove_unique_constraint_on_integration_name/migration.sql +2 -0
  46. package/prisma/migrations/20250514144228_add_vercel_check/migration.sql +2 -0
  47. package/prisma/migrations/20250514150021_add_vercel_verification/migration.sql +2 -0
  48. package/prisma/migrations/20250514161440_add_dates_to_framework_editor_tables/migration.sql +23 -0
  49. package/prisma/migrations/20250515123635_trust_portal_friendly_url/migration.sql +21 -0
  50. package/prisma/migrations/20250515124040_fix_trust_constraints/migration.sql +11 -0
  51. package/prisma/migrations/20250516125758_patch_framework_id_in_editor/migration.sql +6 -0
  52. package/prisma/migrations/20250516132431_add_many_to_many_support_to_tasks/migration.sql +69 -0
  53. package/prisma/migrations/20250516142234_make_entity_optional/migration.sql +3 -0
  54. package/prisma/migrations/20250516145149_drop_entity_and_entity_type/migration.sql +16 -0
  55. package/prisma/migrations/20250516150558_drop_task_type/migration.sql +2 -0
  56. package/prisma/migrations/20250516160714_insert_hardcoded_framework_to_db/migration.sql +37 -0
  57. package/prisma/migrations/20250516161852_cast_framework_id_and_requirement_id_to_string/migration.sql +5 -0
  58. package/prisma/migrations/20250516162324_convert_ids_to_new_format/migration.sql +31 -0
  59. package/prisma/migrations/20250516162730_convert_framework_id/migration.sql +5 -0
  60. package/prisma/migrations/20250516163156_added_relation_to_framework_and_requirement_maps/migration.sql +5 -0
  61. package/prisma/migrations/20250516164307_drop_enums/migration.sql +5 -0
  62. package/prisma/migrations/20250516194123_add_cal_option/migration.sql +2 -0
  63. package/prisma/migrations/20250518133218_add_booking_details/migration.sql +2 -0
  64. package/prisma/migrations/20250519141733_change_framework_id_to_string/migration.sql +3 -0
  65. package/prisma/migrations/20250519141735_drop_enum_on_requirements_map/migration.sql +2 -0
  66. package/prisma/migrations/20250519142913_add_template_references_to_instances/migration.sql +17 -0
  67. package/prisma/migrations/20250519172353_drop_artifacts/migration.sql +56 -0
  68. package/prisma/migrations/20250519204449_drop_relation_between_controls_and_framewrok_instance/migration.sql +14 -0
  69. package/prisma/migrations/20250519212347_add_visibility_toggle_to_framework_editor/migration.sql +2 -0
  70. package/prisma/migrations/20250520152548_add_approver_to_policy/migration.sql +5 -0
  71. package/prisma/migrations/20250520175109_add_description_to_audit_log_for_convenience/migration.sql +2 -0
  72. package/prisma/migrations/20250520175523_add_member_id_to_log_table/migration.sql +8 -0
  73. package/prisma/migrations/20250521140239_add_entity_type_and_id_for_audit_logs_for_easy_filtering/migration.sql +9 -0
  74. package/prisma/migrations/20250603135046_add_v2_onboarding_requirements/migration.sql +36 -0
  75. package/prisma/migrations/20250604155610_add_job_id_column_to_onboarding/migration.sql +2 -0
  76. package/prisma/migrations/20250605151521_make_framework_visibility_false/migration.sql +2 -0
  77. package/prisma/migrations/20250605184738_add_cascade_to_entities_owned_by_org/migration.sql +29 -0
  78. package/prisma/migrations/20250605184740_add_device_agent_details_to_org/migration.sql +18 -0
  79. package/prisma/migrations/20250609130129_add_not_relevant/migration.sql +2 -0
  80. package/prisma/migrations/20250610215328_add_fleet_label_to_employees/migration.sql +2 -0
  81. package/prisma/migrations/20250611144654_add_is_fleet_setup_flag/migration.sql +2 -0
  82. package/prisma/migrations/20250612160731_remove_unused_cols/migration.sql +10 -0
  83. package/prisma/migrations/20250618001304_add_default_slug/migration.sql +3 -0
  84. package/prisma/migrations/20250623184529_add_subscription_type/migration.sql +12 -0
  85. package/prisma/migrations/20250626021946_add_starter_subscription_type/migration.sql +27 -0
  86. package/prisma/migrations/20250626030206_added_new_subscription_type/migration.sql +2 -0
  87. package/prisma/migrations/20250627180331_add_onboaridng_field/migration.sql +5 -0
  88. package/prisma/migrations/20250627180828_rename_completed_col/migration.sql +15 -0
  89. package/prisma/migrations/20250708152414_add_had_call_col/migration.sql +2 -0
  90. package/prisma/migrations/20250711201749_update_retool_role_to_edit_had_call_column_in_organization_table/migration.sql +7 -0
  91. package/prisma/migrations/20250711204234_add_read_permission_for_where_clause_on_retool_role/migration.sql +8 -0
  92. package/prisma/migrations/20250714153009_remove_stripe_and_add_has_access/migration.sql +31 -0
  93. package/prisma/migrations/20250715200054_add_perms_for_has_access_for_retool/migration.sql +7 -0
  94. package/prisma/migrations/migration_lock.toml +3 -0
  95. package/prisma/randomSecret.sql +12 -0
  96. package/prisma/schema/attachments.prisma +35 -0
  97. package/prisma/schema/auth.prisma +122 -0
  98. package/prisma/schema/comment.prisma +27 -0
  99. package/prisma/schema/context.prisma +18 -0
  100. package/prisma/schema/control.prisma +21 -0
  101. package/prisma/schema/framework-editor.prisma +96 -0
  102. package/prisma/schema/framework.prisma +14 -0
  103. package/prisma/schema/integration.prisma +32 -0
  104. package/prisma/schema/onboarding.prisma +18 -0
  105. package/prisma/schema/organization.prisma +34 -0
  106. package/prisma/schema/policy.prisma +32 -0
  107. package/prisma/schema/requirement.prisma +15 -0
  108. package/prisma/schema/risk.prisma +57 -0
  109. package/prisma/schema/shared.prisma +104 -0
  110. package/prisma/schema/task.prisma +41 -0
  111. package/prisma/schema/trust.prisma +37 -0
  112. package/prisma/schema/vendor.prisma +56 -0
  113. package/prisma/schema.prisma +12 -0
  114. package/prisma/seed/frameworkEditorSchemas.js +136 -0
  115. package/prisma/seed/frameworkEditorSchemas.ts +178 -0
  116. package/prisma/seed/primitives/FrameworkEditorControlTemplate.json +296 -0
  117. package/prisma/seed/primitives/FrameworkEditorFramework.json +101 -0
  118. package/prisma/seed/primitives/FrameworkEditorPolicyTemplate.json +6057 -0
  119. package/prisma/seed/primitives/FrameworkEditorRequirement.json +7841 -0
  120. package/prisma/seed/primitives/FrameworkEditorTaskTemplate.json +308 -0
  121. package/prisma/seed/primitives/FrameworkEditorVideo.json +47 -0
  122. package/prisma/seed/relations/_FrameworkEditorControlTemplateToFrameworkEditorPolicyTemplate.json +178 -0
  123. package/prisma/seed/relations/_FrameworkEditorControlTemplateToFrameworkEditorRequirement.json +470 -0
  124. package/prisma/seed/relations/_FrameworkEditorControlTemplateToFrameworkEditorTaskTemplate.json +142 -0
  125. package/prisma/seed/seed.js +160 -0
  126. package/prisma/seed/seed.ts +192 -0
  127. package/scripts/setup-consumer.sh +62 -0
package/README.md CHANGED
@@ -1,41 +1,71 @@
1
1
  # @trycompai/db
2
2
 
3
- Database package with Prisma client and schema for Comp AI applications.
3
+ Shared Prisma schema and types for Comp AI applications.
4
+
5
+ ## What This Package Provides
6
+
7
+ - 📄 **Prisma Schema**: The source of truth for the database structure
8
+ - 🏷️ **TypeScript Types**: Fully typed models for use across applications
9
+ - 🔧 **Migration Files**: Database migrations to keep schemas in sync
4
10
 
5
11
  ## Installation
6
12
 
7
13
  ```bash
8
- npm install @trycompai/db @prisma/client
14
+ # In your app directory
15
+ npm install @trycompai/db @prisma/client prisma
9
16
  # or
10
- bun add @trycompai/db @prisma/client
17
+ bun add @trycompai/db @prisma/client prisma
11
18
  ```
12
19
 
13
- ## Usage
20
+ ## Setup
21
+
22
+ 1. **Generate Prisma Client** in your app:
23
+
24
+ ```bash
25
+ # Run this in your app directory after installing
26
+ npx prisma generate --schema=node_modules/@trycompai/db/prisma/schema.prisma
27
+ ```
28
+
29
+ 2. **Create your database instance** (`lib/db.ts`):
14
30
 
15
31
  ```typescript
16
- import { db, PrismaClient, Prisma } from '@trycompai/db';
32
+ import { PrismaClient } from '@prisma/client';
17
33
 
18
- // Use the pre-configured db instance (recommended)
19
- const users = await db.user.findMany();
34
+ const globalForPrisma = globalThis as unknown as {
35
+ prisma: PrismaClient | undefined;
36
+ };
20
37
 
21
- // Or create your own client
22
- const client = new PrismaClient();
38
+ export const db =
39
+ globalForPrisma.prisma ??
40
+ new PrismaClient({
41
+ log: ['warn', 'error'],
42
+ });
23
43
 
24
- // Full TypeScript support for all Prisma types
25
- type User = Prisma.UserCreateInput;
44
+ if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
26
45
  ```
27
46
 
28
- ## Environment Variables
47
+ 3. **Use in your app**:
29
48
 
30
- Set your `DATABASE_URL` environment variable:
49
+ ```typescript
50
+ import { db } from '@/lib/db';
51
+ import type { User, Organization } from '@trycompai/db';
31
52
 
32
- ```env
33
- DATABASE_URL="postgresql://user:password@localhost:5432/database"
53
+ // Full type safety!
54
+ const users: User[] = await db.user.findMany();
34
55
  ```
35
56
 
36
- ## Key Features
57
+ ## Why This Approach?
58
+
59
+ - ✅ **Platform-specific binaries**: Each app generates its own query engine
60
+ - ✅ **Proper connection management**: Each app manages its own connections
61
+ - ✅ **Type safety**: Share types without runtime coupling
62
+ - ✅ **Monorepo friendly**: Works seamlessly with any monorepo setup
63
+
64
+ ## Development
65
+
66
+ To update the schema:
37
67
 
38
- - **Zero setup**: Just install and use - no additional configuration needed
39
- - **Server-side only**: Safe for use in server environments
40
- - **Full TypeScript support**: Complete type definitions for all database models
41
- - **Pre-configured client**: Ready-to-use database connection with optimized settings
68
+ 1. Edit `prisma/schema.prisma` in this package
69
+ 2. Run migrations: `bun run db:migrate`
70
+ 3. Regenerate types: `bun run build`
71
+ 4. Update version and publish
package/dist/index.d.mts CHANGED
@@ -1,10 +1,5 @@
1
- import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
- import { PrismaClient } from '@prisma/client';
3
- export { Prisma, PrismaClient } from '@prisma/client';
1
+ export { Organization, Prisma, PrismaClient, User } from '@prisma/client';
4
2
 
5
- declare const db: PrismaClient<{
6
- datasourceUrl: string | undefined;
7
- log: ("warn" | "error")[];
8
- }, never, _prisma_client_runtime_library.DefaultArgs>;
3
+ declare const DATABASE_URL: string;
9
4
 
10
- export { db };
5
+ export { DATABASE_URL };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,5 @@
1
- import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
- import { PrismaClient } from '@prisma/client';
3
- export { Prisma, PrismaClient } from '@prisma/client';
1
+ export { Organization, Prisma, PrismaClient, User } from '@prisma/client';
4
2
 
5
- declare const db: PrismaClient<{
6
- datasourceUrl: string | undefined;
7
- log: ("warn" | "error")[];
8
- }, never, _prisma_client_runtime_library.DefaultArgs>;
3
+ declare const DATABASE_URL: string;
9
4
 
10
- export { db };
5
+ export { DATABASE_URL };
package/dist/index.js CHANGED
@@ -20,23 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- PrismaClient: () => import_client2.PrismaClient,
24
- db: () => db
23
+ DATABASE_URL: () => DATABASE_URL
25
24
  });
26
25
  module.exports = __toCommonJS(index_exports);
27
- var import_client = require("@prisma/client");
28
- var import_client2 = require("@prisma/client");
29
- var createPrismaClient = () => {
30
- return new import_client.PrismaClient({
31
- datasourceUrl: process.env.DATABASE_URL,
32
- log: ["error", "warn"]
33
- });
34
- };
35
- var globalForPrisma = globalThis;
36
- var db = globalForPrisma.prisma ?? createPrismaClient();
37
- if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
26
+ var DATABASE_URL = process.env.DATABASE_URL || "";
38
27
  // Annotate the CommonJS export names for ESM import in node:
39
28
  0 && (module.exports = {
40
- PrismaClient,
41
- db
29
+ DATABASE_URL
42
30
  });
package/dist/index.mjs CHANGED
@@ -1,16 +1,5 @@
1
1
  // src/index.ts
2
- import { PrismaClient } from "@prisma/client";
3
- import { PrismaClient as PrismaClient2 } from "@prisma/client";
4
- var createPrismaClient = () => {
5
- return new PrismaClient({
6
- datasourceUrl: process.env.DATABASE_URL,
7
- log: ["error", "warn"]
8
- });
9
- };
10
- var globalForPrisma = globalThis;
11
- var db = globalForPrisma.prisma ?? createPrismaClient();
12
- if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
2
+ var DATABASE_URL = process.env.DATABASE_URL || "";
13
3
  export {
14
- PrismaClient2 as PrismaClient,
15
- db
4
+ DATABASE_URL
16
5
  };
@@ -1,7 +1,7 @@
1
1
  generator client {
2
2
  provider = "prisma-client-js"
3
- previewFeatures = ["driverAdapters", "postgresqlExtensions", "prismaSchemaFolder"]
4
- binaryTargets = ["native", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"]
3
+ previewFeatures = ["driverAdapters", "postgresqlExtensions"]
4
+ binaryTargets = ["native", "darwin-arm64", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"]
5
5
  }
6
6
 
7
7
  datasource db {
@@ -0,0 +1,7 @@
1
+ import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
+ import * as _prisma_client from '@prisma/client';
3
+ import { PrismaClient } from '@prisma/client';
4
+
5
+ declare const db: PrismaClient<_prisma_client.Prisma.PrismaClientOptions, never, _prisma_client_runtime_library.DefaultArgs>;
6
+
7
+ export { db };
@@ -0,0 +1,7 @@
1
+ import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
+ import * as _prisma_client from '@prisma/client';
3
+ import { PrismaClient } from '@prisma/client';
4
+
5
+ declare const db: PrismaClient<_prisma_client.Prisma.PrismaClientOptions, never, _prisma_client_runtime_library.DefaultArgs>;
6
+
7
+ export { db };
package/dist/setup.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/setup.ts
21
+ var setup_exports = {};
22
+ __export(setup_exports, {
23
+ db: () => db
24
+ });
25
+ module.exports = __toCommonJS(setup_exports);
26
+ var import_client = require("@prisma/client");
27
+ var globalForPrisma = globalThis;
28
+ var db = globalForPrisma.prisma ?? new import_client.PrismaClient({
29
+ log: ["warn", "error"]
30
+ });
31
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
32
+ // Annotate the CommonJS export names for ESM import in node:
33
+ 0 && (module.exports = {
34
+ db
35
+ });
package/dist/setup.mjs ADDED
@@ -0,0 +1,10 @@
1
+ // src/setup.ts
2
+ import { PrismaClient } from "@prisma/client";
3
+ var globalForPrisma = globalThis;
4
+ var db = globalForPrisma.prisma ?? new PrismaClient({
5
+ log: ["warn", "error"]
6
+ });
7
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
8
+ export {
9
+ db
10
+ };
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@trycompai/db",
3
3
  "description": "Database package with Prisma client and schema for Comp AI",
4
- "version": "1.0.7",
5
- "peerDependencies": {
6
- "@prisma/client": "^6.9.0"
7
- },
8
- "dependencies": {
9
- "prisma": "6.9.0"
10
- },
4
+ "version": "1.0.9",
11
5
  "devDependencies": {
6
+ "@prisma/client": "6.9.0",
7
+ "prisma": "6.9.0",
12
8
  "@trycompai/tsconfig": "workspace:*",
13
9
  "ts-node": "^10.9.2",
14
10
  "tsup": "^8.5.0",
15
11
  "typescript": "^5.8.3"
16
12
  },
13
+ "peerDependencies": {
14
+ "@prisma/client": "^6.9.0",
15
+ "prisma": "^6.9.0"
16
+ },
17
17
  "exports": {
18
18
  ".": {
19
19
  "types": "./dist/index.d.ts",
@@ -24,10 +24,18 @@
24
24
  "types": "./dist/types.d.ts",
25
25
  "import": "./dist/types.mjs",
26
26
  "require": "./dist/types.js"
27
- }
27
+ },
28
+ "./setup": {
29
+ "types": "./dist/setup.d.ts",
30
+ "import": "./dist/setup.mjs",
31
+ "require": "./dist/setup.js"
32
+ },
33
+ "./prisma/schema": "./prisma/schema.prisma"
28
34
  },
29
35
  "files": [
30
36
  "dist/**",
37
+ "prisma/**",
38
+ "scripts/**",
31
39
  "README.md"
32
40
  ],
33
41
  "keywords": [
@@ -70,7 +78,8 @@
70
78
  "tsup": {
71
79
  "entry": [
72
80
  "src/index.ts",
73
- "src/types.ts"
81
+ "src/types.ts",
82
+ "src/setup.ts"
74
83
  ],
75
84
  "format": [
76
85
  "cjs",
@@ -0,0 +1,18 @@
1
+ -- Create function to generate prefixed CUID with sortable timestamp (compact)
2
+ CREATE OR REPLACE FUNCTION generate_prefixed_cuid(prefix text)
3
+ RETURNS text AS $$
4
+ DECLARE
5
+ timestamp_hex text;
6
+ random_hex text;
7
+ BEGIN
8
+ -- Generate timestamp component (seconds since epoch) as hex
9
+ timestamp_hex = LOWER(TO_HEX(EXTRACT(EPOCH FROM NOW())::BIGINT));
10
+
11
+ -- Generate 8 random bytes and encode as hex (16 characters)
12
+ -- Ensure we call the function from the correct schema if pgcrypto is installed elsewhere
13
+ random_hex = encode(gen_random_bytes(8), 'hex');
14
+
15
+ -- Combine prefix, timestamp, and random hex string
16
+ RETURN prefix || '_' || timestamp_hex || random_hex;
17
+ END;
18
+ $$ LANGUAGE plpgsql;