diff --git a/.gitignore b/.gitignore index 2959b0f20..7840e7c55 100644 --- a/.gitignore +++ b/.gitignore @@ -83,9 +83,6 @@ next-env.d.ts *.rdb -shared/drizzle - - run.sh commands.sh env.sh diff --git a/ai b/ai index a6d3ad040..b1efb8d30 160000 --- a/ai +++ b/ai @@ -1 +1 @@ -Subproject commit a6d3ad040325b2cf6ba4f171c367e4a95fbac8ed +Subproject commit b1efb8d303caf7fdc76d820b00ad87d305f6867f diff --git a/bun.lock b/bun.lock index 1bd4c803c..7f35eec0c 100644 --- a/bun.lock +++ b/bun.lock @@ -315,10 +315,12 @@ "inquirer": "^12.6.3", "ioredis": "^5.10.0", "p-limit": "^7.2.0", + "pg": "8.20.0", "react": "^18.3.1", }, "devDependencies": { "@types/bun": "^1.3.11", + "@types/pg": "8.11.10", "@types/react": "^18.3.1", "tsx": "^4.19.2", "typescript": "^5.7.3", @@ -2438,7 +2440,7 @@ "@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="], - "@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "@types/pg": ["@types/pg@8.11.10", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^4.0.1" } }, "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg=="], "@types/pg-pool": ["@types/pg-pool@2.0.7", "", { "dependencies": { "@types/pg": "*" } }, "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng=="], @@ -4678,6 +4680,8 @@ "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], + "obuf": ["obuf@1.1.2", "", {}, "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="], + "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], @@ -4816,11 +4820,13 @@ "pg-node-migrations": ["pg-node-migrations@0.0.8", "", { "dependencies": { "pg": "^8.6.0", "sql-template-strings": "^2.2.2" }, "bin": { "pg-validate-migrations": "dist/bin/validate.js" } }, "sha512-44cMl9umOmCv0hzZyEcvjEq8Bm8u7mrzggZ06qXTJVSsMMB4j2OsjG+rSp+uzeKWyP2Vu0K9Ye2wKtjFUJwrdw=="], + "pg-numeric": ["pg-numeric@1.0.2", "", {}, "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw=="], + "pg-pool": ["pg-pool@3.13.0", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA=="], "pg-protocol": ["pg-protocol@1.13.0", "", {}, "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w=="], - "pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "pg-types": ["pg-types@4.1.0", "", { "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", "postgres-array": "~3.0.1", "postgres-bytea": "~3.0.0", "postgres-date": "~2.1.0", "postgres-interval": "^3.0.0", "postgres-range": "^1.1.1" } }, "sha512-o2XFanIMy/3+mThw69O8d4n1E5zsLhdO+OPqswezu7Z5ekP4hYDqlDjlmOpYMbzY2Br0ufCwJLdDIXeNVwcWFg=="], "pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="], @@ -4888,13 +4894,15 @@ "postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="], - "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + "postgres-array": ["postgres-array@3.0.4", "", {}, "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ=="], - "postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + "postgres-bytea": ["postgres-bytea@3.0.0", "", { "dependencies": { "obuf": "~1.1.2" } }, "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw=="], - "postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + "postgres-date": ["postgres-date@2.1.0", "", {}, "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA=="], - "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "postgres-interval": ["postgres-interval@3.0.0", "", {}, "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw=="], + + "postgres-range": ["postgres-range@1.1.4", "", {}, "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w=="], "posthog-js": ["posthog-js@1.372.10", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@posthog/core": "1.28.4", "@posthog/types": "1.372.10", "core-js": "^3.38.1", "dompurify": "^3.3.2", "fflate": "^0.4.8", "preact": "^10.28.2", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^5.1.0" } }, "sha512-ZQslIenDM8UpwKhmeeEnJ+t2nXr8mOIjCG+Ej3DCJnTBk9NX9Sr5RMuwHeGG8UJitwvtGOADyiY7DignOXaZwg=="], @@ -5930,6 +5938,8 @@ "@autumn/server/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + "@autumn/server/@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "@autumn/server/@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260511.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260511.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260511.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260511.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260511.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260511.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260511.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260511.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-cUyY4Sr6065280lB6hCwTMCBMTxlEIGjSLzHym28yikA5sFiEsAzlwiU0i+XkTUIqr5K5M/SzSJiioDN+vpjtA=="], "@autumn/server/autumn-js": ["autumn-js@0.1.85", "", { "dependencies": { "query-string": "^9.2.2", "rou3": "^0.6.1", "swr": "^2.3.3", "zod": "^4.0.0" }, "peerDependencies": { "better-auth": "^1.3.17", "better-call": "^1.0.12", "convex": "^1.25.4", "react": "*" }, "optionalPeers": ["better-auth", "better-call", "convex", "react"] }, "sha512-PDud/t8z5bDJcD7ptyHzTaoJ0A8zkxvQ4TYcJ48RtgKDdOkVY36D1T6udVLwLDnWw4J5KXwJgEuGxHdd+cuABw=="], @@ -5938,6 +5948,8 @@ "@autumn/shared/@date-fns/utc": ["@date-fns/utc@2.1.0", "", {}, "sha512-176grgAgU2U303rD2/vcOmNg0kGPbhzckuH1TEP2al7n0AQipZIy9P15usd2TKQCG1g+E1jX/ZVQSzs4sUDwgA=="], + "@autumn/stripe-sync/@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "@autumn/vite/@types/node": ["@types/node@22.19.19", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew=="], "@autumn/vite/date-fns": ["date-fns@3.6.0", "", {}, "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww=="], @@ -6134,6 +6146,8 @@ "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@better-auth/cli/@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "@better-auth/cli/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], "@better-auth/cli/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], @@ -6834,6 +6848,8 @@ "@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + "@types/pg-pool/@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "@types/react-syntax-highlighter/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], "@types/responselike/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], @@ -7346,6 +7362,8 @@ "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "pino/pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], "pino-pretty/pino-abstract-transport": ["pino-abstract-transport@3.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg=="], @@ -7462,6 +7480,8 @@ "sdk-test/@types/node": ["@types/node@20.19.41", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ=="], + "sdk-test/@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], + "sdk-test/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], "sdk-test/@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], @@ -7710,6 +7730,8 @@ "@autumn/server/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@autumn/server/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "@autumn/server/@typescript/native-preview/@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260511.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-SYrqVOlapDxDG7FzHBIJbfgaix+mXPkYzYGqwpz/TAhoPA7sgbfAoGLaqi3ut9N88C/OYNhEX4tjz/0PC9i1nw=="], "@autumn/server/@typescript/native-preview/@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260511.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zIe31OYgBvkgTIQEwJtKim6SYyuVTkr+9fK/87hVwKN15X3Ikjeh0C0g2W/Vl4rXeMvy95wBGDN1jpW11DIvgg=="], @@ -7748,6 +7770,10 @@ "@autumn/server/ink/widest-line": ["widest-line@6.0.0", "", { "dependencies": { "string-width": "^8.1.0" } }, "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA=="], + "@autumn/stripe-sync/@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + + "@autumn/stripe-sync/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "@autumn/vite/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], "@autumn/website/eslint/@eslint/config-array": ["@eslint/config-array@0.23.5", "", { "dependencies": { "@eslint/object-schema": "^3.0.5", "debug": "^4.3.1", "minimatch": "^10.2.4" } }, "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA=="], @@ -7866,6 +7892,10 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@better-auth/cli/@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + + "@better-auth/cli/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "@datadog/datadog-api-client/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], "@dotenvx/dotenvx/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], @@ -8314,6 +8344,8 @@ "@opentelemetry/instrumentation-pg/@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + "@opentelemetry/instrumentation-pg/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "@opentelemetry/instrumentation-redis/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.211.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg=="], "@opentelemetry/instrumentation-redis/@opentelemetry/instrumentation/import-in-the-middle": ["import-in-the-middle@2.0.6", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw=="], @@ -8478,6 +8510,10 @@ "@types/node-fetch/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@types/pg-pool/@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + + "@types/pg-pool/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], "@types/responselike/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], @@ -8938,6 +8974,14 @@ "p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + "pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "pkg-conf/find-up/locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], "pkg-conf/find-up/path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], @@ -9072,6 +9116,10 @@ "sdk-test/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + "sdk-test/@types/pg/@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + + "sdk-test/@types/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + "sdk-test/next/@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="], "sdk-test/next/@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="], @@ -9230,10 +9278,28 @@ "@artilleryio/int-core/socket.io-client/engine.io-client/xmlhttprequest-ssl": ["xmlhttprequest-ssl@2.1.2", "", {}, "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ=="], + "@autumn/server/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "@autumn/server/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "@autumn/server/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "@autumn/server/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "@autumn/server/ink/@alcalzone/ansi-tokenize/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], "@autumn/server/ink/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + "@autumn/stripe-sync/@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@autumn/stripe-sync/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "@autumn/stripe-sync/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "@autumn/stripe-sync/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "@autumn/stripe-sync/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "@autumn/website/eslint/@eslint/config-array/@eslint/object-schema": ["@eslint/object-schema@3.0.5", "", {}, "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw=="], "@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], @@ -9298,6 +9364,16 @@ "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@1.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw=="], + "@better-auth/cli/@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@better-auth/cli/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "@better-auth/cli/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "@better-auth/cli/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "@better-auth/cli/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "@dotenvx/dotenvx/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], "@eslint/config-array/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -9580,6 +9656,14 @@ "@opentelemetry/instrumentation-pg/@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@opentelemetry/instrumentation-pg/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "@opentelemetry/instrumentation-pg/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "@opentelemetry/instrumentation-pg/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "@opentelemetry/instrumentation-pg/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "@opentelemetry/instrumentation-redis/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="], "@opentelemetry/instrumentation-tedious/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="], @@ -9642,6 +9726,16 @@ "@types/bun/bun-types/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@types/pg-pool/@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@types/pg-pool/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "@types/pg-pool/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "@types/pg-pool/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "@types/pg-pool/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "artillery-plugin-ensure/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], "artillery-plugin-ensure/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], @@ -9878,6 +9972,16 @@ "run-jxa/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "sdk-test/@types/pg/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "sdk-test/@types/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "sdk-test/@types/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "sdk-test/@types/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "sdk-test/@types/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + "sdk-test/next/postcss/nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], "shadcn/cosmiconfig/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], diff --git a/package.json b/package.json index 0f48be32e..331b202ba 100644 --- a/package.json +++ b/package.json @@ -112,9 +112,7 @@ "setupci": "node scripts/setup/setupci.js", "replicate": "bun scripts/db/replicate.ts", "db:pull": "bun scripts/db/pull.ts", - "db:push": " bun -F @autumn/shared db:push", - "db:generate": "bun -F @autumn/shared db:generate", - "db:migrate": " bun -F @autumn/shared db:migrate", + "db": "bun scripts/db/index.ts", "test:integration": "cd server && bun test:integration", "exp": "sh -c 'infisical run --recursive --env=staging -- bun run server/experiments/$0'", "q": "lsof -ti:8080 -ti:3000 | xargs kill -9", diff --git a/scripts/db/README.md b/scripts/db/README.md new file mode 100644 index 000000000..167e2ae82 --- /dev/null +++ b/scripts/db/README.md @@ -0,0 +1,168 @@ +# `bun db` — Drizzle Migration CLI + +Unified entrypoint for everything migration-related. Subcommands route through `scripts/db/index.ts`, which auto-wraps DB-touching subcommands in `infisical run` so `DATABASE_URL` is injected from the right secret environment. + +## Surface + +``` +bun db help # print usage +bun db generate # write a new migration .sql from schema changes +bun db migrate [--env=dev|staging|prod] # apply pending migrations to the target DB +bun db migrate:dry [--env=dev|staging|prod] # preview pending SQL + safety checks, don't apply +bun db mark-applied [--env=dev|staging|prod] # seed drizzle.__drizzle_migrations on an existing DB +bun db rebase # auto-resolve a local migration that collided with origin/dev +``` + +`migrate` and `migrate:dry` also run a safety check that **refuses to apply any pending migration containing `CREATE INDEX`, `DROP INDEX`, or `REINDEX` without `CONCURRENTLY`**. Those DDL statements take an ACCESS EXCLUSIVE lock and can block reads/writes on busy tables. To get through the check: either rewrite the SQL with `CONCURRENTLY` and apply manually + `mark-applied`, or add `.concurrently()` to the index in your schema and regenerate. + +`--env` defaults to `dev`. `generate` and `rebase` never touch a DB and don't take `--env`. + +--- + +## Day-to-day workflow + +```bash +# 1. Make a schema change in shared/db/**.ts or shared/models/**.ts +# 2. Generate the migration +bun db generate + +# 3. Review the new shared/drizzle/{N}_*.sql and updated meta/. +# Commit both with the code change in your PR. + +# 4. Apply locally +bun db migrate +``` + +If your branch's migration collides with one that landed on `origin/dev` first (CI will tell you via duplicate-idx errors), pull and run: + +```bash +git pull origin dev +bun db rebase # auto-renumbers your migration, regenerates against the new baseline +``` + +`bun db rebase` is idempotent and bails out cleanly if drizzle-kit would need interactive input (e.g. column rename detection) — see the "Edge cases" section below. + +--- + +## Bootstrapping a new DB + +`bun db migrate` won't run against a DB that has the tables but no `drizzle.__drizzle_migrations` tracking row — it'd try to `CREATE TABLE` on tables that already exist and fail. Seed the tracking table first: + +```bash +bun db mark-applied # local dev DB +bun db mark-applied --env=staging # if/when staging is wired up — see below +bun db mark-applied --env=prod # if/when prod is wired up — see below +``` + +Idempotent. Re-running is safe. + +--- + +## Status: staging & prod are NOT wired into the CLI yet + +**Right now, staging and prod migrations are still applied manually (paste the `.sql` into TablePlus per env).** The `--env=staging|prod` plumbing exists in the code and works, but we haven't: + +1. Run `bun db mark-applied --env=staging` / `--env=prod` to seed the tracking table on those DBs. +2. Switched the deploy pipeline to call `bun db migrate --env=…` automatically. + +Until both happen, **do not run `bun db migrate --env=staging` or `--env=prod`** — without the mark-applied step, it will try to re-create existing tables and fail. (Failing safely, but failing.) + +--- + +## Upgrade path: moving staging / prod into the CLI + +When you're ready to flip from "TablePlus paste" to automated migrations on a shared env, the sequence is: + +### One-time per env + +1. **Confirm the env's secret name in infisical.** The CLI assumes: + - `dev` → infisical env `dev`, `ENV_FILE=.env` + - `staging` → infisical env `staging`, `ENV_FILE=.env.staging` + - `prod` → infisical env `prod`, `ENV_FILE=.env.prod` + + This mapping lives in `scripts/db/helpers/env.ts`. If your infisical env names diverge, update there. + +2. **Confirm `DATABASE_URL` in that infisical env points at the right DB.** A wrong URL here means migrations apply to the wrong DB. Run: + + ```bash + bun db mark-applied --env= + ``` + + The first log line prints the host parsed from `DATABASE_URL` (e.g. `host=staging-pg.foo.com:5432`) — verify it before letting the script run further. Hit Ctrl-C if it's wrong; mark-applied does its writes after the log line. + +3. **Run mark-applied.** Same command as step 2. It seeds `drizzle.__drizzle_migrations` with rows for every migration currently in `shared/drizzle/meta/_journal.json`, so `db migrate` will skip them. + +4. **Verify migrate is a clean no-op.** This proves the seeding worked: + + ```bash + bun db migrate --env= + ``` + + Expected: drizzle-kit reports "applied successfully" with no DDL run, and `drizzle.__drizzle_migrations` has the same row count as before. + +### Ongoing — moving the apply step from TablePlus to the CLI / CI + +Once the bootstrap above is done for an env, you have two ways to apply new migrations: + +- **Manual command**, same shape as dev: + ```bash + bun db migrate --env=staging + bun db migrate --env=prod + ``` + +- **CI-based** — call the same command from a deploy step. Two things to wire up in the pipeline: + + 1. The CI runner needs `infisical` installed and authenticated with credentials that can read the relevant env. Existing workflows that use `infisical run --env=…` are the precedent; copy that auth setup. + 2. Add a step like: + ```yaml + - name: Apply DB migrations + run: bun db migrate --env=prod + ``` + after the build step and before traffic is shifted to the new revision. If the migration fails, the deploy should halt — `bun db migrate` exits non-zero on any DDL failure. + + Recommendation: **start with staging-only CI migration first**, run it for a week or two, and only then enable prod. Prod migration failures during a deploy are high-blast-radius and you want to be confident the pipeline works before you bet a deploy on it. + +--- + +## File layout + +``` +scripts/db/ +├── README.md # this file +├── index.ts # subcommand dispatch +├── commands/ +│ ├── help.ts +│ ├── generate.ts # passthrough to `bun -F @autumn/shared db:generate` +│ ├── migrate.ts # passthrough to `bun -F @autumn/shared db:migrate` +│ ├── markApplied.ts # seeds drizzle.__drizzle_migrations +│ └── rebase.ts # auto-resolves duplicate-idx conflicts +├── helpers/ +│ ├── env.ts # --env parsing + infisical wrap + DATABASE_URL host extraction +│ ├── paths.ts # canonical paths to shared/drizzle/ and meta/ +│ └── spawn.ts # thin child_process.spawn wrapper +└── pull.ts # unrelated — customer data pull (legacy) +``` + +`shared/package.json` still owns the implementation of `db:generate` and `db:migrate` (which are what the CLI shells out to under the hood). The unified `bun db` interface lives at the repo root. + +--- + +## Edge cases + +### `bun db rebase` bailed with "drizzle-kit needs interactive input" + +This happens when the regeneration would prompt for a rename decision (column renamed, enum value reordered, etc.). The script restored your original files from a temp backup and exited non-zero. Recovery: + +1. `bun db generate` directly in a terminal — answer the prompts. +2. Drizzle will produce a new migration. If it has a duplicate idx with `origin/dev`, manually rename the `.sql` file and update the `idx` + `tag` in `meta/_journal.json`. +3. Re-run `bun db rebase` to confirm the journal is now clean. + +This is rare. ~95% of migrations (ADD COLUMN, DROP COLUMN, CREATE INDEX) auto-resolve cleanly. + +### CI says "migration idx N already exists" + +Someone else's PR with the same migration idx merged first. Run `bun db rebase` on your branch, push, re-run CI. + +### "I deleted shared/drizzle/ by accident" + +Pull from `origin/dev` to get it back. Your in-flight schema changes in TS are still intact; run `bun db generate` and it'll regenerate the migration. diff --git a/scripts/db/commands/generate.ts b/scripts/db/commands/generate.ts new file mode 100644 index 000000000..2a694ceec --- /dev/null +++ b/scripts/db/commands/generate.ts @@ -0,0 +1,11 @@ +import { run } from "../helpers/spawn.ts"; +import { REPO_ROOT } from "../helpers/paths.ts"; + +export async function cmdGenerate(): Promise { + const { code } = await run( + "bun", + ["-F", "@autumn/shared", "db:generate"], + { cwd: REPO_ROOT }, + ); + process.exit(code); +} diff --git a/scripts/db/commands/help.ts b/scripts/db/commands/help.ts new file mode 100644 index 000000000..3b68ebaa9 --- /dev/null +++ b/scripts/db/commands/help.ts @@ -0,0 +1,19 @@ +export function cmdHelp(): void { + const lines = [ + "", + " bun db [--env=dev|staging|prod]", + "", + " Subcommands:", + " help print this message", + " generate write a new migration .sql file from schema changes", + " migrate apply pending migrations to the target DB", + " migrate:dry preview pending migrations (SQL + safety checks), don't apply", + " mark-applied bootstrap drizzle.__drizzle_migrations on an existing DB", + " rebase resolve a local migration that collided with one on origin/dev", + "", + " --env defaults to dev. migrate and mark-applied auto-wrap themselves", + " in `infisical run` so DATABASE_URL is injected automatically.", + "", + ]; + process.stdout.write(`${lines.join("\n")}\n`); +} diff --git a/scripts/db/commands/markApplied.ts b/scripts/db/commands/markApplied.ts new file mode 100644 index 000000000..76cb0c3ad --- /dev/null +++ b/scripts/db/commands/markApplied.ts @@ -0,0 +1,64 @@ +import { readMigrationFiles } from "drizzle-orm/migrator"; +import pg from "pg"; +import { MIGRATIONS_DIR } from "../helpers/paths.ts"; +import { type Env, targetHost, wrapInInfisical } from "../helpers/env.ts"; + +export async function cmdMarkApplied(env: Env): Promise { + await wrapInInfisical(env); + + const databaseUrl = process.env.DATABASE_URL; + if (!databaseUrl) { + console.error("DATABASE_URL not set after infisical wrap"); + process.exit(1); + } + + console.log( + `[db:mark-applied] env=${env} host=${targetHost(databaseUrl)} migrations=${MIGRATIONS_DIR}`, + ); + + const migrations = readMigrationFiles({ migrationsFolder: MIGRATIONS_DIR }); + if (migrations.length === 0) { + console.log("no migrations on disk — nothing to mark"); + return; + } + + const client = new pg.Client({ connectionString: databaseUrl }); + await client.connect(); + + try { + await client.query(`CREATE SCHEMA IF NOT EXISTS "drizzle"`); + await client.query(` + CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at bigint + ) + `); + + let marked = 0; + let already = 0; + for (const migration of migrations) { + const existing = await client.query<{ id: number }>( + `SELECT id FROM "drizzle"."__drizzle_migrations" WHERE hash = $1 LIMIT 1`, + [migration.hash], + ); + + if (existing.rowCount && existing.rowCount > 0) { + console.log(` already applied hash=${migration.hash.slice(0, 12)}…`); + already++; + continue; + } + + await client.query( + `INSERT INTO "drizzle"."__drizzle_migrations" ("hash", "created_at") VALUES ($1, $2)`, + [migration.hash, migration.folderMillis], + ); + console.log(` marked hash=${migration.hash.slice(0, 12)}… when=${migration.folderMillis}`); + marked++; + } + + console.log(`done — marked=${marked} already=${already} total=${migrations.length}`); + } finally { + await client.end(); + } +} diff --git a/scripts/db/commands/migrate.ts b/scripts/db/commands/migrate.ts new file mode 100644 index 000000000..5b70dff2e --- /dev/null +++ b/scripts/db/commands/migrate.ts @@ -0,0 +1,132 @@ +import pg from "pg"; +import { run } from "../helpers/spawn.ts"; +import { REPO_ROOT } from "../helpers/paths.ts"; +import { type Env, targetHost, wrapInInfisical } from "../helpers/env.ts"; +import { + getPendingMigrations, + type PendingMigration, +} from "../helpers/pendingMigrations.ts"; +import { + type BlockingStatement, + findBlockingIndexStatements, +} from "../helpers/safetyCheck.ts"; + +export async function cmdMigrate( + env: Env, + opts: { dryRun: boolean; bootstrap: boolean }, +): Promise { + await wrapInInfisical(env); + + const databaseUrl = process.env.DATABASE_URL; + if (!databaseUrl) { + console.error("DATABASE_URL not set after infisical wrap"); + process.exit(1); + } + + const tags = [ + opts.dryRun ? "DRY" : null, + opts.bootstrap ? "BOOTSTRAP" : null, + ].filter(Boolean); + const tagStr = tags.length > 0 ? ` (${tags.join(" ")})` : ""; + console.log(`[db:migrate${tagStr}] env=${env} host=${targetHost(databaseUrl)}`); + + if (opts.bootstrap) { + console.log( + "bootstrap mode: skipping index-DDL safety check (use only for fresh DBs)", + ); + } + + const client = new pg.Client({ connectionString: databaseUrl }); + await client.connect(); + let pending: PendingMigration[]; + try { + pending = await getPendingMigrations(client); + } finally { + await client.end(); + } + + if (pending.length === 0) { + console.log("no pending migrations"); + return; + } + + console.log(`${pending.length} pending migration(s):`); + for (const migration of pending) { + console.log(` ${migration.tag}`); + } + + const blockers = opts.bootstrap ? [] : collectBlockers(pending); + + if (opts.dryRun) { + console.log(""); + console.log("--- SQL preview ---"); + for (const migration of pending) { + console.log(""); + console.log(`-- ${migration.tag}.sql --`); + console.log(migration.sql); + } + console.log(""); + if (blockers.length > 0) { + printBlockerError(blockers); + console.log("dry-run: would refuse to apply."); + process.exit(1); + } + console.log( + `dry-run: ok — \`bun db migrate --env=${env}\` would apply these.`, + ); + return; + } + + if (blockers.length > 0) { + printBlockerError(blockers); + process.exit(1); + } + + const { code } = await run("bun", ["-F", "@autumn/shared", "db:migrate"], { + cwd: REPO_ROOT, + }); + process.exit(code); +} + +type FlaggedBlocker = { + migration: PendingMigration; + blocker: BlockingStatement; +}; + +function collectBlockers(pending: PendingMigration[]): FlaggedBlocker[] { + const all: FlaggedBlocker[] = []; + for (const migration of pending) { + for (const blocker of findBlockingIndexStatements(migration.sql)) { + all.push({ migration, blocker }); + } + } + return all; +} + +function printBlockerError(blockers: FlaggedBlocker[]): void { + console.error(""); + console.error( + `refusing to apply ${blockers.length} index DDL statement(s) without CONCURRENTLY:`, + ); + for (const { migration, blocker } of blockers) { + console.error(""); + console.error(` in ${migration.tag}.sql [${blocker.kind}]`); + const indented = blocker.statement + .split("\n") + .map((line) => ` ${line}`) + .join("\n"); + console.error(indented); + } + console.error(""); + console.error( + "Index DDL without CONCURRENTLY takes an ACCESS EXCLUSIVE lock that blocks reads/writes on the table.", + ); + console.error(""); + console.error("Options:"); + console.error( + " 1. Apply this migration manually (psql / TablePlus) with CONCURRENTLY, then `bun db mark-applied --env=` to record it.", + ); + console.error( + " 2. If the table is fresh or empty, add `.concurrently()` to the index in shared/db schema, `bun db generate`, and re-try.", + ); +} diff --git a/scripts/db/commands/rebase.ts b/scripts/db/commands/rebase.ts new file mode 100644 index 000000000..64fe875d1 --- /dev/null +++ b/scripts/db/commands/rebase.ts @@ -0,0 +1,180 @@ +import { mkdtempSync, copyFileSync, existsSync, rmSync, writeFileSync, readFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { run } from "../helpers/spawn.ts"; +import { REPO_ROOT, MIGRATIONS_DIR, META_DIR, JOURNAL_PATH } from "../helpers/paths.ts"; + +type JournalEntry = { + idx: number; + version: string; + when: number; + tag: string; + breakpoints: boolean; +}; + +type Journal = { + version: string; + dialect: string; + entries: JournalEntry[]; +}; + +const REMOTE_REF = "origin/dev"; + +export async function cmdRebase(): Promise { + // 1. Bail on unresolved schema conflicts. + const unmerged = await run("git", ["diff", "--name-only", "--diff-filter=U"], { + cwd: REPO_ROOT, + stdio: "pipe", + }); + if (unmerged.code !== 0) { + console.error(`git diff failed:\n${unmerged.stderr}`); + process.exit(1); + } + const schemaConflicts = unmerged.stdout + .split("\n") + .filter((line) => line.startsWith("shared/db/")); + if (schemaConflicts.length > 0) { + console.error( + `unresolved schema conflicts — resolve these first:\n${schemaConflicts.map((f) => ` ${f}`).join("\n")}`, + ); + process.exit(1); + } + + // 2. Read local + remote journals. + const localJournal = readLocalJournal(); + const remoteJournal = await readRemoteJournal(); + + if (!remoteJournal) { + console.log(`nothing to rebase — could not read ${REMOTE_REF}:shared/drizzle/meta/_journal.json (no remote yet?)`); + return; + } + + // 3. Find orphaned local entries — same idx as remote, but different tag/when. + const remoteByIdx = new Map(); + for (const entry of remoteJournal.entries) remoteByIdx.set(entry.idx, entry); + + const orphans: JournalEntry[] = []; + for (const entry of localJournal.entries) { + const remoteEntry = remoteByIdx.get(entry.idx); + if (!remoteEntry) continue; + if (remoteEntry.tag !== entry.tag || remoteEntry.when !== entry.when) { + orphans.push(entry); + } + } + + if (orphans.length === 0) { + console.log("no migration conflicts — nothing to rebase"); + return; + } + + console.log(`found ${orphans.length} orphaned local migration(s):`); + for (const orphan of orphans) { + console.log(` idx=${orphan.idx} tag=${orphan.tag}`); + } + + // 4. Back up the orphaned files. + const backupDir = mkdtempSync(join(tmpdir(), "autumn-db-rebase-")); + console.log(`backup dir: ${backupDir}`); + + const backups: Array<{ src: string; backup: string }> = []; + for (const orphan of orphans) { + const sql = join(MIGRATIONS_DIR, `${orphan.tag}.sql`); + const snapshot = join(META_DIR, `${formatIdx(orphan.idx)}_snapshot.json`); + for (const src of [sql, snapshot]) { + if (!existsSync(src)) continue; + const backup = join(backupDir, src.replace(/[/\\]/g, "_")); + copyFileSync(src, backup); + backups.push({ src, backup }); + } + } + + // 5. Delete orphans, then restore canonical journal + snapshots from origin/dev. + for (const orphan of orphans) { + const sql = join(MIGRATIONS_DIR, `${orphan.tag}.sql`); + const snapshot = join(META_DIR, `${formatIdx(orphan.idx)}_snapshot.json`); + if (existsSync(sql)) rmSync(sql); + if (existsSync(snapshot)) rmSync(snapshot); + } + + const remoteJournalRaw = await gitShow(`${REMOTE_REF}:shared/drizzle/meta/_journal.json`); + if (remoteJournalRaw === null) { + restoreBackups(backups); + console.error("failed to fetch remote journal — aborted, backups restored"); + process.exit(1); + } + writeFileSync(JOURNAL_PATH, remoteJournalRaw); + + for (const orphan of orphans) { + const snapshotPath = `${REMOTE_REF}:shared/drizzle/meta/${formatIdx(orphan.idx)}_snapshot.json`; + const remoteEntry = remoteByIdx.get(orphan.idx); + if (!remoteEntry) continue; + const snapshotRaw = await gitShow(snapshotPath); + if (snapshotRaw === null) { + restoreBackups(backups); + console.error(`failed to fetch ${snapshotPath} — aborted, backups restored`); + process.exit(1); + } + writeFileSync(join(META_DIR, `${formatIdx(orphan.idx)}_snapshot.json`), snapshotRaw); + } + + // 6. Regenerate non-interactively. drizzle-kit reads stdin for rename prompts; + // closing stdin makes it fail fast rather than hang. + const generate = await run("bun", ["-F", "@autumn/shared", "db:generate"], { + cwd: REPO_ROOT, + stdio: "pipe", + }); + + if (generate.code !== 0) { + restoreBackups(backups); + console.error("`db:generate` failed during rebase — backups restored."); + console.error(""); + console.error("Likely cause: drizzle-kit needs interactive input (e.g. column rename detection)."); + console.error("Resolve manually:"); + console.error(" 1. Run `bun db:generate` directly in a terminal and answer prompts."); + console.error(" 2. If a duplicate-idx file is produced, delete it and re-run."); + console.error(""); + console.error("drizzle-kit stderr:"); + console.error(generate.stderr); + process.exit(1); + } + + console.log(generate.stdout); + + // 7. Stage everything for the engineer. + await run("git", ["add", "shared/drizzle/"], { cwd: REPO_ROOT }); + + console.log(""); + console.log("rebase complete — review the regenerated migration and commit."); + console.log(`backup retained at: ${backupDir}`); +} + +function readLocalJournal(): Journal { + const raw = readFileSync(JOURNAL_PATH, "utf8"); + return JSON.parse(raw) as Journal; +} + +async function readRemoteJournal(): Promise { + const raw = await gitShow(`${REMOTE_REF}:shared/drizzle/meta/_journal.json`); + if (raw === null) return null; + return JSON.parse(raw) as Journal; +} + +async function gitShow(ref: string): Promise { + const result = await run("git", ["show", ref], { cwd: REPO_ROOT, stdio: "pipe" }); + if (result.code !== 0) return null; + return result.stdout; +} + +function restoreBackups(backups: Array<{ src: string; backup: string }>): void { + for (const { src, backup } of backups) { + try { + copyFileSync(backup, src); + } catch { + // best-effort restore + } + } +} + +function formatIdx(idx: number): string { + return idx.toString().padStart(4, "0"); +} diff --git a/scripts/db/helpers/env.ts b/scripts/db/helpers/env.ts new file mode 100644 index 000000000..d38fd8622 --- /dev/null +++ b/scripts/db/helpers/env.ts @@ -0,0 +1,84 @@ +import { spawn } from "node:child_process"; + +export type Env = "dev" | "staging" | "prod"; + +const VALID_ENVS: readonly Env[] = ["dev", "staging", "prod"] as const; + +export function parseEnv(argv: readonly string[]): Env { + for (const arg of argv) { + if (arg.startsWith("--env=")) { + const value = arg.slice("--env=".length); + if (!VALID_ENVS.includes(value as Env)) { + console.error( + `invalid --env=${value}, must be one of: ${VALID_ENVS.join(", ")}`, + ); + process.exit(2); + } + return value as Env; + } + } + return "dev"; +} + +const ENV_FILE: Record = { + dev: ".env", + staging: ".env.staging", + prod: ".env.prod", +}; + +/** + * If not already inside an infisical-wrapped context, re-exec this process + * wrapped in `infisical run --env= --recursive --` so DATABASE_URL is + * injected from the right secret environment. Returns true if we re-exec'd + * (caller should exit); false if already wrapped (caller should proceed). + */ +export async function wrapInInfisical(env: Env): Promise { + if (process.env.AUTUMN_DB_WRAPPED === "1") return false; + + if (process.env.AUTUMN_DB_DIRECT === "1") { + if (!process.env.DATABASE_URL) { + console.error( + "AUTUMN_DB_DIRECT=1 but DATABASE_URL not set — caller must inject the URL when bypassing infisical", + ); + process.exit(1); + } + return false; + } + + const args = [ + "run", + `--env=${env}`, + "--recursive", + "--", + "bun", + ...process.argv.slice(1), + ]; + + const child = spawn("infisical", args, { + stdio: "inherit", + env: { + ...process.env, + AUTUMN_DB_WRAPPED: "1", + ENV_FILE: ENV_FILE[env], + }, + }); + + const code: number = await new Promise((resolve) => { + child.on("close", (c) => resolve(c ?? 1)); + child.on("error", (err) => { + console.error(`failed to spawn infisical: ${err.message}`); + resolve(1); + }); + }); + process.exit(code); +} + +export function targetHost(databaseUrl: string | undefined): string { + if (!databaseUrl) return ""; + try { + const url = new URL(databaseUrl); + return url.host; + } catch { + return ""; + } +} diff --git a/scripts/db/helpers/paths.ts b/scripts/db/helpers/paths.ts new file mode 100644 index 000000000..7b16dd149 --- /dev/null +++ b/scripts/db/helpers/paths.ts @@ -0,0 +1,9 @@ +import { fileURLToPath } from "node:url"; +import { dirname, resolve } from "node:path"; + +const here = dirname(fileURLToPath(import.meta.url)); + +export const REPO_ROOT = resolve(here, "../../.."); +export const MIGRATIONS_DIR = resolve(REPO_ROOT, "shared/drizzle"); +export const META_DIR = resolve(MIGRATIONS_DIR, "meta"); +export const JOURNAL_PATH = resolve(META_DIR, "_journal.json"); diff --git a/scripts/db/helpers/pendingMigrations.ts b/scripts/db/helpers/pendingMigrations.ts new file mode 100644 index 000000000..bcdf5ac5a --- /dev/null +++ b/scripts/db/helpers/pendingMigrations.ts @@ -0,0 +1,55 @@ +import { readFileSync } from "node:fs"; +import { join } from "node:path"; +import type pg from "pg"; +import { JOURNAL_PATH, MIGRATIONS_DIR } from "./paths.ts"; + +export type JournalEntry = { + idx: number; + version: string; + when: number; + tag: string; + breakpoints: boolean; +}; + +export type PendingMigration = JournalEntry & { + sql: string; + sqlPath: string; +}; + +/** + * Returns migrations on disk that haven't been recorded in drizzle.__drizzle_migrations yet. + * Mirrors drizzle-kit's filter: anything in _journal.json whose `when` is greater than the + * largest `created_at` already in the tracking table. + */ +export async function getPendingMigrations( + client: pg.Client, +): Promise { + await client.query(`CREATE SCHEMA IF NOT EXISTS "drizzle"`); + await client.query(` + CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at bigint + ) + `); + + const result = await client.query<{ created_at: string | null }>( + `SELECT created_at FROM "drizzle"."__drizzle_migrations" ORDER BY created_at DESC LIMIT 1`, + ); + const lastApplied = + result.rowCount && result.rowCount > 0 && result.rows[0].created_at !== null + ? Number(result.rows[0].created_at) + : null; + + const journal = JSON.parse(readFileSync(JOURNAL_PATH, "utf8")) as { + entries: JournalEntry[]; + }; + + return journal.entries + .filter((entry) => lastApplied === null || entry.when > lastApplied) + .map((entry) => { + const sqlPath = join(MIGRATIONS_DIR, `${entry.tag}.sql`); + const sql = readFileSync(sqlPath, "utf8"); + return { ...entry, sql, sqlPath }; + }); +} diff --git a/scripts/db/helpers/safetyCheck.ts b/scripts/db/helpers/safetyCheck.ts new file mode 100644 index 000000000..979b257cb --- /dev/null +++ b/scripts/db/helpers/safetyCheck.ts @@ -0,0 +1,26 @@ +const INDEX_DDL = /^\s*(CREATE\s+(UNIQUE\s+)?INDEX|DROP\s+INDEX|REINDEX)\b/i; +const HAS_CONCURRENTLY = /\bCONCURRENTLY\b/i; + +export type BlockingStatement = { + kind: "CREATE INDEX" | "DROP INDEX" | "REINDEX"; + statement: string; +}; + +export function findBlockingIndexStatements(sql: string): BlockingStatement[] { + const blockers: BlockingStatement[] = []; + const statements = sql.split("--> statement-breakpoint"); + for (const raw of statements) { + const trimmed = raw.trim(); + if (!trimmed) continue; + if (!INDEX_DDL.test(trimmed)) continue; + if (HAS_CONCURRENTLY.test(trimmed)) continue; + const upper = trimmed.toUpperCase(); + const kind: BlockingStatement["kind"] = upper.startsWith("CREATE") + ? "CREATE INDEX" + : upper.startsWith("DROP") + ? "DROP INDEX" + : "REINDEX"; + blockers.push({ kind, statement: trimmed }); + } + return blockers; +} diff --git a/scripts/db/helpers/spawn.ts b/scripts/db/helpers/spawn.ts new file mode 100644 index 000000000..b9558e096 --- /dev/null +++ b/scripts/db/helpers/spawn.ts @@ -0,0 +1,46 @@ +import { spawn } from "node:child_process"; + +export type RunOptions = { + cwd?: string; + env?: NodeJS.ProcessEnv; + stdio?: "inherit" | "pipe"; +}; + +export type RunResult = { + code: number; + stdout: string; + stderr: string; +}; + +export function run( + cmd: string, + args: readonly string[], + options: RunOptions = {}, +): Promise { + const { cwd, env, stdio = "inherit" } = options; + return new Promise((resolve) => { + const child = spawn(cmd, [...args], { + cwd, + env: env ?? process.env, + stdio: stdio === "inherit" ? "inherit" : ["ignore", "pipe", "pipe"], + }); + + let stdout = ""; + let stderr = ""; + if (stdio === "pipe") { + child.stdout?.on("data", (chunk: Buffer) => { + stdout += chunk.toString(); + }); + child.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); + } + + child.on("close", (code) => { + resolve({ code: code ?? 1, stdout, stderr }); + }); + child.on("error", (err) => { + resolve({ code: 1, stdout, stderr: stderr + err.message }); + }); + }); +} diff --git a/scripts/db/index.ts b/scripts/db/index.ts new file mode 100644 index 000000000..dbb60c894 --- /dev/null +++ b/scripts/db/index.ts @@ -0,0 +1,46 @@ +import { cmdHelp } from "./commands/help.ts"; +import { cmdGenerate } from "./commands/generate.ts"; +import { cmdMigrate } from "./commands/migrate.ts"; +import { cmdMarkApplied } from "./commands/markApplied.ts"; +import { cmdRebase } from "./commands/rebase.ts"; +import { parseEnv } from "./helpers/env.ts"; + +async function main(): Promise { + const sub = process.argv[2]; + const rest = process.argv.slice(3); + + if (!sub || sub === "help" || sub === "--help" || sub === "-h") { + cmdHelp(); + return; + } + + switch (sub) { + case "generate": + await cmdGenerate(); + return; + case "migrate": + await cmdMigrate(parseEnv(rest), { + dryRun: false, + bootstrap: rest.includes("--bootstrap"), + }); + return; + case "migrate:dry": + await cmdMigrate(parseEnv(rest), { + dryRun: true, + bootstrap: rest.includes("--bootstrap"), + }); + return; + case "mark-applied": + await cmdMarkApplied(parseEnv(rest)); + return; + case "rebase": + await cmdRebase(); + return; + default: + console.error(`unknown subcommand: ${sub}`); + cmdHelp(); + process.exit(2); + } +} + +await main(); diff --git a/scripts/dw/helpers/migration.ts b/scripts/dw/helpers/migration.ts index 047eb07ab..0d1ae716b 100644 --- a/scripts/dw/helpers/migration.ts +++ b/scripts/dw/helpers/migration.ts @@ -1,71 +1,33 @@ -import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { readFileSync } from "node:fs"; import { join } from "node:path"; -import { sh, fatal, log } from "./shell.ts"; -import { SHARED_DIR, PROJECT_ROOT } from "../constants.ts"; +import { sh, shInherit, fatal, log } from "./shell.ts"; +import { PROJECT_ROOT } from "../constants.ts"; -export function listSqlFiles(dir: string): string[] { - if (!existsSync(dir)) return []; - return readdirSync(dir).filter((f) => f.endsWith(".sql")); -} - -export function writeTempDrizzleConfig(outDir: string): string { - const tmp = join(SHARED_DIR, `.dw-${process.pid}.config.ts`); - const content = `import { defineConfig } from "drizzle-kit";\nexport default defineConfig({\n\tdialect: "postgresql",\n\tout: ${JSON.stringify(outDir)},\n\tschema: "./db/schema.ts",\n\tdbCredentials: { url: process.env.DATABASE_URL! },\n});\n`; - writeFileSync(tmp, content); - return tmp; -} - -export function generateAndApplyMigration( +/** + * Brings a freshly-provisioned Neon branch up to the canonical schema. + * + * Strategy: invoke the shared `bun db migrate --bootstrap` CLI with the new + * branch's DATABASE_URL injected directly (bypassing infisical). `--bootstrap` + * skips the index-DDL safety check, which is safe here because the DB is empty + * and has no concurrent traffic. + */ +export function applyCommittedMigrations( branchName: string, databaseUrl: string, ): void { - // Use the worktree's own shared/drizzle/ as the migration dir (matches - // drizzle.config.ts out: "./drizzle"). Empty it first so the baseline - // generated for this fresh Neon branch isn't a diff against the canonical - // repo's migration history — subsequent `bun db:generate` runs then emit - // clean incrementals against this worktree's actual DB state. - const outDir = join(SHARED_DIR, "drizzle"); - if (existsSync(outDir)) rmSync(outDir, { recursive: true, force: true }); - mkdirSync(outDir, { recursive: true }); + log(`applying committed migrations to ${branchName}`); - const drizzleConfigPath = writeTempDrizzleConfig(outDir); - try { - log(`generating initial migration for ${branchName}`); - const gen = sh( - "bunx", - ["drizzle-kit", "generate", "--config", drizzleConfigPath], - { - cwd: SHARED_DIR, - env: { - ...(process.env as Record), - NODE_OPTIONS: "--import tsx", - }, - }, - ); - if (gen.code !== 0) { - fatal(`drizzle-kit generate failed:\n${gen.stdout}\n${gen.stderr}`); - } + const code = shInherit("bun", ["db", "migrate", "--bootstrap"], { + cwd: PROJECT_ROOT, + env: { + ...(process.env as Record), + DATABASE_URL: databaseUrl, + AUTUMN_DB_DIRECT: "1", + }, + }); - const sqlFiles = listSqlFiles(outDir); - if (sqlFiles.length === 0) { - fatal(`no .sql files generated in ${outDir}`); - } - - log(`applying ${sqlFiles.length} migration file(s) to ${branchName}`); - for (const f of sqlFiles) { - const p = join(outDir, f); - const sqlBody = readFileSync(p, "utf-8"); - const mig = sh("psql", [databaseUrl, "-v", "ON_ERROR_STOP=1"], { - stdin: sqlBody, - }); - if (mig.code !== 0) { - fatal( - `applying migration ${f} failed:\n${mig.stdout}\n${mig.stderr}`, - ); - } - } - } finally { - if (existsSync(drizzleConfigPath)) rmSync(drizzleConfigPath); + if (code !== 0) { + fatal(`bun db migrate --bootstrap failed for ${branchName} (exit ${code})`); } } diff --git a/scripts/dw/helpers/setup.ts b/scripts/dw/helpers/setup.ts index e848223a5..9523015c9 100644 --- a/scripts/dw/helpers/setup.ts +++ b/scripts/dw/helpers/setup.ts @@ -5,7 +5,7 @@ import { connectionString, findBranchByName, } from "./neon.ts"; -import { generateAndApplyMigration, loadDbFunctions } from "./migration.ts"; +import { applyCommittedMigrations, loadDbFunctions } from "./migration.ts"; import { loadRegistry, saveRegistry } from "./registry.ts"; import { PROJECT_ROOT, NEON_TEMPLATE_BRANCH } from "../constants.ts"; import type { RegistryEntry } from "../types.ts"; @@ -36,7 +36,7 @@ export async function setupAgentWorktree( const branch = createBranch(branchName, NEON_TEMPLATE_BRANCH); // Use direct (non-pooled) URL for DDL; pooler can interfere with some DDL paths. const directUrl = connectionString(branchName, { pooled: false }); - generateAndApplyMigration(branchName, directUrl); + applyCommittedMigrations(branchName, directUrl); loadDbFunctions(branchName, directUrl); // Pooled URL for runtime. const pooledUrl = connectionString(branchName, { pooled: true }); diff --git a/scripts/package.json b/scripts/package.json index 4f59b111f..7e7b1e7c3 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -19,10 +19,12 @@ "ioredis": "^5.10.0", "inquirer": "^12.6.3", "p-limit": "^7.2.0", + "pg": "8.20.0", "react": "^18.3.1" }, "devDependencies": { "@types/bun": "^1.3.11", + "@types/pg": "8.11.10", "@types/react": "^18.3.1", "tsx": "^4.19.2", "typescript": "^5.7.3" diff --git a/shared/drizzle/0000_bumpy_tinkerer.sql b/shared/drizzle/0000_bumpy_tinkerer.sql new file mode 100644 index 000000000..742f53d05 --- /dev/null +++ b/shared/drizzle/0000_bumpy_tinkerer.sql @@ -0,0 +1,882 @@ +CREATE TABLE "account" ( + "id" text PRIMARY KEY NOT NULL, + "account_id" text NOT NULL, + "provider_id" text NOT NULL, + "user_id" text NOT NULL, + "access_token" text, + "refresh_token" text, + "id_token" text, + "access_token_expires_at" timestamp, + "refresh_token_expires_at" timestamp, + "scope" text, + "password" text, + "created_at" timestamp with time zone NOT NULL, + "updated_at" timestamp with time zone NOT NULL +); +--> statement-breakpoint +ALTER TABLE "account" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "actions" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "request_id" text NOT NULL, + "org_id" text NOT NULL, + "org_slug" text NOT NULL, + "env" text NOT NULL, + "customer_id" text, + "internal_customer_id" text, + "entity_id" text, + "internal_entity_id" text, + "type" text NOT NULL, + "auth_type" text NOT NULL, + "method" text NOT NULL, + "path" text NOT NULL, + "timestamp" timestamp with time zone DEFAULT now() NOT NULL, + "properties" jsonb +); +--> statement-breakpoint +ALTER TABLE "actions" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "api_keys" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "name" text, + "prefix" text, + "org_id" text, + "user_id" text, + "env" text, + "hashed_key" text, + "meta" jsonb, + "scopes" jsonb, + CONSTRAINT "api_keys_hashed_key_key" UNIQUE("hashed_key") +); +--> statement-breakpoint +CREATE TABLE "auto_topup_limit_states" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "internal_customer_id" text NOT NULL, + "customer_id" text NOT NULL, + "feature_id" text NOT NULL, + "purchase_window_ends_at" numeric NOT NULL, + "purchase_count" numeric DEFAULT 0 NOT NULL, + "attempt_window_ends_at" numeric NOT NULL, + "attempt_count" numeric DEFAULT 0 NOT NULL, + "failed_attempt_window_ends_at" numeric NOT NULL, + "failed_attempt_count" numeric DEFAULT 0 NOT NULL, + "last_attempt_at" numeric, + "last_failed_attempt_at" numeric, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "updated_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL +); +--> statement-breakpoint +CREATE TABLE "chat_results" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "created_at" numeric, + "data" jsonb NOT NULL +); +--> statement-breakpoint +ALTER TABLE "chat_results" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "checkouts" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "internal_customer_id" text NOT NULL, + "customer_id" text NOT NULL, + "action" text NOT NULL, + "params" jsonb NOT NULL, + "params_version" integer DEFAULT 0 NOT NULL, + "status" text DEFAULT 'pending' NOT NULL, + "response" jsonb, + "stripe_invoice_id" text, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "expires_at" numeric NOT NULL, + "completed_at" numeric +); +--> statement-breakpoint +CREATE TABLE "customer_entitlements" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "customer_product_id" text, + "entitlement_id" text NOT NULL, + "internal_customer_id" text COLLATE "C" NOT NULL, + "internal_entity_id" text, + "internal_feature_id" text NOT NULL, + "unlimited" boolean DEFAULT false, + "balance" numeric DEFAULT 0 NOT NULL, + "created_at" numeric NOT NULL, + "next_reset_at" numeric, + "usage_allowed" boolean DEFAULT false, + "adjustment" numeric, + "additional_balance" numeric DEFAULT 0 NOT NULL, + "entities" jsonb, + "expires_at" numeric, + "cache_version" integer DEFAULT 0, + "customer_id" text, + "feature_id" text, + "external_id" text +); +--> statement-breakpoint +CREATE TABLE "customer_prices" ( + "id" text PRIMARY KEY NOT NULL, + "created_at" numeric NOT NULL, + "price_id" text, + "options" jsonb, + "internal_customer_id" text, + "customer_product_id" text +); +--> statement-breakpoint +CREATE TABLE "customer_products" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "internal_customer_id" text NOT NULL, + "internal_product_id" text NOT NULL, + "internal_entity_id" text, + "created_at" numeric, + "updated_at" numeric, + "status" text, + "processor" jsonb, + "canceled" boolean DEFAULT false, + "canceled_at" numeric, + "ended_at" numeric, + "starts_at" numeric, + "access_starts_at" numeric, + "options" jsonb[], + "product_id" text, + "free_trial_id" text, + "trial_ends_at" numeric, + "billing_cycle_anchor_resets_at" numeric, + "collection_method" text DEFAULT 'charge_automatically', + "subscription_ids" text[], + "scheduled_ids" text[], + "quantity" numeric DEFAULT 1, + "is_custom" boolean DEFAULT false NOT NULL, + "customer_id" text, + "entity_id" text, + "billing_version" text, + "api_version" numeric, + "api_semver" text, + "external_id" text, + "stripe_checkout_session_id" text, + "previous_customer_product_id" text, + "on_trial_end" text +); +--> statement-breakpoint +CREATE TABLE "customers" ( + "internal_id" text COLLATE "C" PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "created_at" numeric NOT NULL, + "name" text, + "id" text, + "email" text, + "fingerprint" text DEFAULT null, + "metadata" jsonb, + "env" text NOT NULL, + "processor" jsonb, + "processors" jsonb DEFAULT '{}'::jsonb, + "send_email_receipts" boolean DEFAULT false, + "auto_topups" jsonb, + "spend_limits" jsonb, + "usage_alerts" jsonb, + "overage_allowed" jsonb, + "config" jsonb DEFAULT '{}'::jsonb, + CONSTRAINT "cus_id_constraint" UNIQUE("org_id","id","env") +); +--> statement-breakpoint +ALTER TABLE "customers" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "entities" ( + "id" text, + "org_id" text, + "created_at" numeric NOT NULL, + "internal_id" text PRIMARY KEY NOT NULL, + "internal_customer_id" text NOT NULL, + "env" text, + "name" text, + "deleted" boolean DEFAULT false NOT NULL, + "internal_feature_id" text, + "spend_limits" jsonb, + "usage_alerts" jsonb, + "overage_allowed" jsonb, + "feature_id" text, + CONSTRAINT "entity_id_constraint" UNIQUE("org_id","env","internal_customer_id","id") +); +--> statement-breakpoint +CREATE TABLE "entitlements" ( + "id" text PRIMARY KEY NOT NULL, + "created_at" numeric NOT NULL, + "internal_feature_id" text NOT NULL, + "internal_product_id" text, + "internal_reward_id" text, + "is_custom" boolean DEFAULT false, + "allowance_type" text, + "allowance" numeric, + "interval" text, + "interval_count" numeric DEFAULT 1, + "carry_from_previous" boolean DEFAULT false, + "entity_feature_id" text DEFAULT null, + "org_id" text, + "feature_id" text, + "usage_limit" numeric, + "expiry_duration" text, + "expiry_length" numeric, + "rollover" jsonb, + CONSTRAINT "entitlements_id_key" UNIQUE("id") +); +--> statement-breakpoint +CREATE TABLE "events" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "org_slug" text NOT NULL, + "internal_customer_id" text, + "env" text NOT NULL, + "created_at" bigint, + "timestamp" timestamp with time zone, + "event_name" text NOT NULL, + "idempotency_key" text DEFAULT null, + "value" numeric, + "set_usage" boolean DEFAULT false, + "entity_id" text, + "internal_entity_id" text, + "internal_product_id" text, + "customer_id" text NOT NULL, + "properties" jsonb, + "deductions" jsonb, + CONSTRAINT "unique_event_constraint" UNIQUE("org_id","env","customer_id","event_name","idempotency_key") +); +--> statement-breakpoint +CREATE TABLE "features" ( + "internal_id" text COLLATE "C" PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "created_at" numeric, + "env" text, + "id" text NOT NULL, + "name" text, + "type" text NOT NULL, + "config" jsonb, + "display" jsonb DEFAULT null, + "archived" boolean DEFAULT false NOT NULL, + "event_names" text[] DEFAULT '{}', + CONSTRAINT "feature_id_constraint" UNIQUE("org_id","id","env") +); +--> statement-breakpoint +CREATE TABLE "free_trials" ( + "id" text PRIMARY KEY NOT NULL, + "created_at" numeric NOT NULL, + "internal_product_id" text, + "duration" text DEFAULT 'day', + "length" numeric, + "unique_fingerprint" boolean, + "is_custom" boolean DEFAULT false, + "card_required" boolean DEFAULT false, + "on_end" text +); +--> statement-breakpoint +CREATE TABLE "invitation" ( + "id" text PRIMARY KEY NOT NULL, + "organization_id" text NOT NULL, + "email" text NOT NULL, + "role" text, + "status" text DEFAULT 'pending' NOT NULL, + "created_at" timestamp with time zone NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "inviter_id" text NOT NULL +); +--> statement-breakpoint +ALTER TABLE "invitation" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "invoice_line_items" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "invoice_id" text, + "stripe_id" text, + "stripe_invoice_id" text, + "stripe_invoice_item_id" text, + "stripe_subscription_item_id" text, + "stripe_product_id" text, + "stripe_price_id" text, + "stripe_discountable" boolean DEFAULT true NOT NULL, + "amount" numeric NOT NULL, + "amount_after_discounts" numeric NOT NULL, + "currency" text DEFAULT 'usd' NOT NULL, + "stripe_quantity" numeric, + "total_quantity" numeric, + "paid_quantity" numeric, + "description" text NOT NULL, + "description_source" text, + "direction" text NOT NULL, + "billing_timing" text, + "prorated" boolean DEFAULT false NOT NULL, + "price_id" text, + "customer_product_ids" jsonb DEFAULT '[]'::jsonb NOT NULL, + "customer_price_ids" jsonb DEFAULT '[]'::jsonb NOT NULL, + "customer_entitlement_ids" jsonb DEFAULT '[]'::jsonb NOT NULL, + "internal_product_id" text, + "product_id" text, + "internal_feature_id" text, + "feature_id" text, + "effective_period_start" numeric, + "effective_period_end" numeric, + "discounts" jsonb[] DEFAULT '{}', + CONSTRAINT "invoice_line_items_stripe_id_unique" UNIQUE("stripe_id") +); +--> statement-breakpoint +CREATE TABLE "invoices" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "product_ids" text[] DEFAULT '{}', + "internal_product_ids" text[] DEFAULT '{}', + "internal_customer_id" text NOT NULL, + "internal_entity_id" text, + "stripe_id" text NOT NULL, + "processor_type" text, + "status" text DEFAULT 'draft' NOT NULL, + "hosted_invoice_url" text, + "total" numeric DEFAULT 0 NOT NULL, + "amount_paid" numeric, + "refunded_amount" numeric DEFAULT 0 NOT NULL, + "currency" text DEFAULT 'usd' NOT NULL, + "discounts" jsonb[] DEFAULT '{}', + "items" jsonb[] DEFAULT '{}', + CONSTRAINT "invoices_stripe_id_key" UNIQUE("stripe_id") +); +--> statement-breakpoint +CREATE TABLE "jwks" ( + "id" text PRIMARY KEY NOT NULL, + "public_key" text NOT NULL, + "private_key" text NOT NULL, + "created_at" timestamp with time zone NOT NULL, + "expires_at" timestamp with time zone +); +--> statement-breakpoint +ALTER TABLE "jwks" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "member" ( + "id" text PRIMARY KEY NOT NULL, + "organization_id" text NOT NULL, + "user_id" text NOT NULL, + "role" text DEFAULT 'member' NOT NULL, + "created_at" timestamp with time zone NOT NULL +); +--> statement-breakpoint +ALTER TABLE "member" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "metadata" ( + "id" text PRIMARY KEY NOT NULL, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "expires_at" numeric, + "data" jsonb, + "type" text, + "stripe_invoice_id" text, + "stripe_checkout_session_id" text +); +--> statement-breakpoint +CREATE TABLE "migration_errors" ( + "internal_customer_id" text NOT NULL, + "migration_job_id" text NOT NULL, + "created_at" numeric, + "updated_at" numeric, + "data" jsonb, + "message" text, + "code" text, + CONSTRAINT "migration_errors_pkey" PRIMARY KEY("internal_customer_id","migration_job_id") +); +--> statement-breakpoint +CREATE TABLE "migration_item_runs" ( + "migration_item_run_id" text PRIMARY KEY NOT NULL, + "migration_internal_id" text NOT NULL, + "migration_run_id" text, + "dry_run" boolean DEFAULT false NOT NULL, + "item_kind" text NOT NULL, + "item_id" text NOT NULL, + "status" text NOT NULL, + "timestamp" timestamp with time zone DEFAULT now() NOT NULL, + "created_at" numeric NOT NULL, + "updated_at" numeric +); +--> statement-breakpoint +CREATE TABLE "migration_jobs" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "created_at" numeric NOT NULL, + "updated_at" numeric, + "current_step" text, + "from_internal_product_id" text, + "to_internal_product_id" text, + "step_details" jsonb +); +--> statement-breakpoint +CREATE TABLE "migration_runs" ( + "internal_id" text PRIMARY KEY NOT NULL, + "migration_internal_id" text NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "status" text NOT NULL, + "dry_run" boolean NOT NULL, + "lazy_run" boolean DEFAULT false NOT NULL, + "trigger_run_id" text, + "error_message" text, + "only_ids" text[], + "created_at" numeric NOT NULL, + "updated_at" numeric, + "started_at" numeric, + "finished_at" numeric +); +--> statement-breakpoint +CREATE TABLE "migrations" ( + "internal_id" text PRIMARY KEY NOT NULL, + "id" text NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "filter" jsonb, + "operations" jsonb, + "prepared_state" jsonb, + "no_billing_changes" boolean, + "retry_failed" boolean DEFAULT false NOT NULL, + "created_at" numeric NOT NULL, + "updated_at" numeric +); +--> statement-breakpoint +CREATE TABLE "oauth_access_token" ( + "id" text PRIMARY KEY NOT NULL, + "token" text, + "client_id" text NOT NULL, + "session_id" text, + "user_id" text, + "reference_id" text, + "refresh_id" text, + "expires_at" timestamp with time zone, + "created_at" timestamp with time zone, + "scopes" text[] NOT NULL, + CONSTRAINT "oauth_access_token_token_unique" UNIQUE("token") +); +--> statement-breakpoint +ALTER TABLE "oauth_access_token" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "oauth_client" ( + "id" text PRIMARY KEY NOT NULL, + "client_id" text NOT NULL, + "client_secret" text, + "disabled" boolean DEFAULT false, + "skip_consent" boolean, + "enable_end_session" boolean, + "scopes" text[], + "user_id" text, + "created_at" timestamp with time zone, + "updated_at" timestamp with time zone, + "name" text, + "uri" text, + "icon" text, + "contacts" text[], + "tos" text, + "policy" text, + "software_id" text, + "software_version" text, + "software_statement" text, + "redirect_uris" text[] NOT NULL, + "post_logout_redirect_uris" text[], + "token_endpoint_auth_method" text, + "grant_types" text[], + "response_types" text[], + "public" boolean, + "type" text, + "reference_id" text, + "metadata" jsonb, + CONSTRAINT "oauth_client_client_id_unique" UNIQUE("client_id") +); +--> statement-breakpoint +ALTER TABLE "oauth_client" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "oauth_consent" ( + "id" text PRIMARY KEY NOT NULL, + "client_id" text NOT NULL, + "user_id" text, + "reference_id" text, + "scopes" text[] NOT NULL, + "created_at" timestamp with time zone, + "updated_at" timestamp with time zone +); +--> statement-breakpoint +ALTER TABLE "oauth_consent" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "oauth_refresh_token" ( + "id" text PRIMARY KEY NOT NULL, + "token" text NOT NULL, + "client_id" text NOT NULL, + "session_id" text, + "user_id" text NOT NULL, + "reference_id" text, + "expires_at" timestamp with time zone, + "created_at" timestamp with time zone, + "revoked" timestamp with time zone, + "scopes" text[] NOT NULL +); +--> statement-breakpoint +ALTER TABLE "oauth_refresh_token" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "organizations" ( + "id" text PRIMARY KEY NOT NULL, + "slug" text NOT NULL, + "name" text NOT NULL, + "logo" text, + "createdAt" timestamp with time zone NOT NULL, + "metadata" text, + "default_currency" text DEFAULT 'usd', + "stripe_connected" boolean DEFAULT false, + "stripe_config" jsonb, + "test_stripe_connect" jsonb DEFAULT '{}'::jsonb, + "live_stripe_connect" jsonb DEFAULT '{}'::jsonb, + "processor_configs" jsonb, + "test_pkey" text, + "live_pkey" text, + "svix_config" jsonb DEFAULT '{}'::jsonb, + "created_at" numeric, + "config" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_by" text, + "onboarded" boolean DEFAULT false, + "deployed" boolean DEFAULT false, + "redis_config" jsonb, + CONSTRAINT "organizations_slug_unique" UNIQUE("slug"), + CONSTRAINT "organizations_test_pkey_key" UNIQUE("test_pkey"), + CONSTRAINT "organizations_live_pkey_key" UNIQUE("live_pkey") +); +--> statement-breakpoint +CREATE TABLE "prices" ( + "id" text COLLATE "C" PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "internal_product_id" text NOT NULL, + "config" jsonb, + "created_at" numeric NOT NULL, + "billing_type" text, + "tier_behavior" text DEFAULT null, + "is_custom" boolean DEFAULT false, + "entitlement_id" text DEFAULT null, + "proration_config" jsonb DEFAULT null, + CONSTRAINT "prices_id_key" UNIQUE("id") +); +--> statement-breakpoint +CREATE TABLE "products" ( + "internal_id" text PRIMARY KEY NOT NULL, + "id" text NOT NULL, + "name" text, + "description" text, + "org_id" text NOT NULL, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "env" text NOT NULL, + "is_add_on" boolean DEFAULT false NOT NULL, + "is_default" boolean DEFAULT false NOT NULL, + "group" text DEFAULT '', + "version" numeric DEFAULT 1 NOT NULL, + "processor" jsonb DEFAULT null, + "base_variant_id" text, + "archived" boolean DEFAULT false NOT NULL, + "config" jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT "unique_product" UNIQUE("org_id","id","env","version") +); +--> statement-breakpoint +CREATE TABLE "referral_codes" ( + "code" text NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "internal_customer_id" text COLLATE "C", + "internal_reward_program_id" text, + "id" text NOT NULL, + "created_at" numeric, + CONSTRAINT "referral_codes_pkey" PRIMARY KEY("code","org_id","env"), + CONSTRAINT "referral_codes_id_key" UNIQUE("id") +); +--> statement-breakpoint +CREATE TABLE "replaceables" ( + "id" text PRIMARY KEY NOT NULL, + "cus_ent_id" text NOT NULL, + "created_at" bigint NOT NULL, + "from_entity_id" text, + "delete_next_cycle" boolean DEFAULT false NOT NULL +); +--> statement-breakpoint +ALTER TABLE "replaceables" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "revenuecat_mappings" ( + "org_id" text NOT NULL, + "env" text NOT NULL, + "autumn_product_id" text NOT NULL, + "revenuecat_product_ids" text[] DEFAULT '{}' NOT NULL, + CONSTRAINT "revenuecat_mappings_pkey" PRIMARY KEY("org_id","env","autumn_product_id") +); +--> statement-breakpoint +CREATE TABLE "reward_programs" ( + "internal_id" text PRIMARY KEY NOT NULL, + "id" text, + "created_at" numeric, + "internal_reward_id" text, + "max_redemptions" numeric, + "unlimited_redemptions" boolean DEFAULT false, + "org_id" text, + "env" text, + "when" text DEFAULT 'immediately', + "product_ids" text[] DEFAULT '{""}', + "exclude_trial" boolean DEFAULT false, + "received_by" text +); +--> statement-breakpoint +CREATE TABLE "reward_redemptions" ( + "id" text PRIMARY KEY NOT NULL, + "created_at" numeric, + "updated_at" numeric, + "internal_customer_id" text COLLATE "C", + "triggered" boolean, + "internal_reward_program_id" text, + "applied" boolean DEFAULT false, + "redeemer_applied" boolean DEFAULT false, + "referral_code_id" text, + "reward_internal_id" text, + "promo_code" text +); +--> statement-breakpoint +CREATE TABLE "rewards" ( + "internal_id" text PRIMARY KEY NOT NULL, + "id" text, + "org_id" text, + "env" text, + "created_at" numeric, + "name" text, + "discount_config" jsonb, + "free_product_config" jsonb, + "free_product_id" text, + "promo_codes" jsonb[], + "type" text +); +--> statement-breakpoint +CREATE TABLE "rollovers" ( + "id" text PRIMARY KEY NOT NULL, + "cus_ent_id" text NOT NULL, + "balance" numeric NOT NULL, + "expires_at" numeric, + "usage" numeric DEFAULT 0 NOT NULL, + "entities" jsonb DEFAULT '{}'::jsonb NOT NULL +); +--> statement-breakpoint +ALTER TABLE "rollovers" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "phases" ( + "id" text PRIMARY KEY NOT NULL, + "schedule_id" text NOT NULL, + "starts_at" numeric NOT NULL, + "customer_product_ids" text[] DEFAULT '{}' NOT NULL, + "created_at" numeric NOT NULL, + CONSTRAINT "phases_schedule_id_starts_at_key" UNIQUE("schedule_id","starts_at") +); +--> statement-breakpoint +CREATE TABLE "schedules" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "internal_customer_id" text NOT NULL, + "customer_id" text NOT NULL, + "internal_entity_id" text, + "entity_id" text, + "created_at" numeric NOT NULL +); +--> statement-breakpoint +CREATE TABLE "session" ( + "id" text PRIMARY KEY NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "token" text NOT NULL, + "created_at" timestamp with time zone NOT NULL, + "updated_at" timestamp with time zone NOT NULL, + "ip_address" text, + "user_agent" text, + "user_id" text NOT NULL, + "impersonated_by" text, + "active_organization_id" text, + "city" text, + "country" text, + CONSTRAINT "session_token_unique" UNIQUE("token") +); +--> statement-breakpoint +ALTER TABLE "session" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +CREATE TABLE "subscriptions" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "stripe_id" text, + "stripe_schedule_id" text, + "created_at" numeric DEFAULT ROUND(date_part('epoch', NOW()) * 1000)::BIGINT NOT NULL, + "metadata" jsonb DEFAULT '{}'::jsonb, + "usage_features" text[] DEFAULT '{}', + "env" text, + "current_period_start" numeric, + "current_period_end" numeric, + CONSTRAINT "subscriptions_stripe_id_key" UNIQUE("stripe_id") +); +--> statement-breakpoint +CREATE TABLE "user" ( + "id" text PRIMARY KEY NOT NULL, + "name" text NOT NULL, + "email" text NOT NULL, + "email_verified" boolean NOT NULL, + "image" text, + "created_at" timestamp with time zone NOT NULL, + "updated_at" timestamp with time zone NOT NULL, + "role" text, + "banned" boolean, + "ban_reason" text, + "ban_expires" timestamp with time zone, + "created_by" text, + "last_active_at" timestamp with time zone, + CONSTRAINT "user_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE "vercel_resources" ( + "id" text PRIMARY KEY NOT NULL, + "org_id" text NOT NULL, + "env" text NOT NULL, + "installation_id" text NOT NULL, + "name" text NOT NULL, + "status" text NOT NULL, + "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL +); +--> statement-breakpoint +CREATE TABLE "verification" ( + "id" text PRIMARY KEY NOT NULL, + "identifier" text NOT NULL, + "value" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "created_at" timestamp with time zone, + "updated_at" timestamp with time zone +); +--> statement-breakpoint +ALTER TABLE "verification" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint +ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "actions" ADD CONSTRAINT "actions_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "actions" ADD CONSTRAINT "actions_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "actions" ADD CONSTRAINT "actions_entity_id_fkey" FOREIGN KEY ("internal_entity_id") REFERENCES "public"."entities"("internal_id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "auto_topup_limit_states" ADD CONSTRAINT "auto_topup_limits_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "auto_topup_limit_states" ADD CONSTRAINT "auto_topup_limits_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_entitlements" ADD CONSTRAINT "entitlements_internal_feature_id_fkey" FOREIGN KEY ("internal_feature_id") REFERENCES "public"."features"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_entitlements" ADD CONSTRAINT "customer_entitlements_internal_entity_id_fkey" FOREIGN KEY ("internal_entity_id") REFERENCES "public"."entities"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_entitlements" ADD CONSTRAINT "customer_entitlements_customer_product_id_fkey" FOREIGN KEY ("customer_product_id") REFERENCES "public"."customer_products"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "customer_entitlements" ADD CONSTRAINT "customer_entitlements_entitlement_id_fkey" FOREIGN KEY ("entitlement_id") REFERENCES "public"."entitlements"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "customer_prices" ADD CONSTRAINT "customer_prices_customer_product_id_fkey" FOREIGN KEY ("customer_product_id") REFERENCES "public"."customer_products"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_prices" ADD CONSTRAINT "customer_prices_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_prices" ADD CONSTRAINT "customer_prices_price_id_fkey" FOREIGN KEY ("price_id") REFERENCES "public"."prices"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_products" ADD CONSTRAINT "customer_products_free_trial_id_fkey" FOREIGN KEY ("free_trial_id") REFERENCES "public"."free_trials"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_products" ADD CONSTRAINT "customer_products_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "customer_products" ADD CONSTRAINT "customer_products_internal_product_id_fkey" FOREIGN KEY ("internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customer_products" ADD CONSTRAINT "customer_products_internal_entity_id_fkey" FOREIGN KEY ("internal_entity_id") REFERENCES "public"."entities"("internal_id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "customers" ADD CONSTRAINT "customers_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entities" ADD CONSTRAINT "entities_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entities" ADD CONSTRAINT "entities_internal_feature_id_fkey" FOREIGN KEY ("internal_feature_id") REFERENCES "public"."features"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entities" ADD CONSTRAINT "entities_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entitlements" ADD CONSTRAINT "entitlements_internal_feature_id_fkey" FOREIGN KEY ("internal_feature_id") REFERENCES "public"."features"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "entitlements" ADD CONSTRAINT "entitlements_internal_product_id_fkey" FOREIGN KEY ("internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "entitlements" ADD CONSTRAINT "entitlements_internal_reward_id_fkey" FOREIGN KEY ("internal_reward_id") REFERENCES "public"."rewards"("internal_id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "events" ADD CONSTRAINT "events_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "features" ADD CONSTRAINT "features_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "free_trials" ADD CONSTRAINT "free_trials_internal_product_id_fkey" FOREIGN KEY ("internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "invitation" ADD CONSTRAINT "invitation_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "invitation" ADD CONSTRAINT "invitation_inviter_id_user_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "invoice_line_items" ADD CONSTRAINT "invoice_line_items_invoice_id_fkey" FOREIGN KEY ("invoice_id") REFERENCES "public"."invoices"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "invoices" ADD CONSTRAINT "invoices_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "invoices" ADD CONSTRAINT "invoices_internal_entity_id_fkey" FOREIGN KEY ("internal_entity_id") REFERENCES "public"."entities"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "member" ADD CONSTRAINT "member_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "member" ADD CONSTRAINT "member_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_errors" ADD CONSTRAINT "migration_customers_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_errors" ADD CONSTRAINT "migration_customers_migration_job_id_fkey" FOREIGN KEY ("migration_job_id") REFERENCES "public"."migration_jobs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_jobs" ADD CONSTRAINT "migration_jobs_from_internal_product_id_fkey" FOREIGN KEY ("from_internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_jobs" ADD CONSTRAINT "migration_jobs_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_jobs" ADD CONSTRAINT "migration_jobs_to_internal_product_id_fkey" FOREIGN KEY ("to_internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_runs" ADD CONSTRAINT "migration_runs_migration_internal_id_fkey" FOREIGN KEY ("migration_internal_id") REFERENCES "public"."migrations"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migration_runs" ADD CONSTRAINT "migration_runs_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "migrations" ADD CONSTRAINT "migrations_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_session_id_session_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."session"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_refresh_id_oauth_refresh_token_id_fk" FOREIGN KEY ("refresh_id") REFERENCES "public"."oauth_refresh_token"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_client" ADD CONSTRAINT "oauth_client_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_session_id_session_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."session"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "prices" ADD CONSTRAINT "prices_entitlement_id_fkey" FOREIGN KEY ("entitlement_id") REFERENCES "public"."entitlements"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "prices" ADD CONSTRAINT "prices_internal_product_id_fkey" FOREIGN KEY ("internal_product_id") REFERENCES "public"."products"("internal_id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "products" ADD CONSTRAINT "products_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "referral_codes" ADD CONSTRAINT "referral_codes_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "referral_codes" ADD CONSTRAINT "referral_codes_internal_reward_program_id_fkey" FOREIGN KEY ("internal_reward_program_id") REFERENCES "public"."reward_programs"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "referral_codes" ADD CONSTRAINT "referral_codes_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "replaceables" ADD CONSTRAINT "replaceables_cus_ent_id_fkey" FOREIGN KEY ("cus_ent_id") REFERENCES "public"."customer_entitlements"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "revenuecat_mappings" ADD CONSTRAINT "revenuecat_mappings_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "reward_programs" ADD CONSTRAINT "reward_triggers_internal_reward_id_fkey" FOREIGN KEY ("internal_reward_id") REFERENCES "public"."rewards"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "reward_programs" ADD CONSTRAINT "reward_triggers_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "reward_redemptions" ADD CONSTRAINT "reward_redemptions_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "reward_redemptions" ADD CONSTRAINT "reward_redemptions_internal_reward_program_id_fkey" FOREIGN KEY ("internal_reward_program_id") REFERENCES "public"."reward_programs"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "reward_redemptions" ADD CONSTRAINT "reward_redemptions_referral_code_id_fkey" FOREIGN KEY ("referral_code_id") REFERENCES "public"."referral_codes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "rewards" ADD CONSTRAINT "coupons_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "rollovers" ADD CONSTRAINT "rollover_cus_ent_id_fkey" FOREIGN KEY ("cus_ent_id") REFERENCES "public"."customer_entitlements"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "phases" ADD CONSTRAINT "phases_schedule_id_fkey" FOREIGN KEY ("schedule_id") REFERENCES "public"."schedules"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "schedules" ADD CONSTRAINT "schedules_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "schedules" ADD CONSTRAINT "schedules_internal_customer_id_fkey" FOREIGN KEY ("internal_customer_id") REFERENCES "public"."customers"("internal_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "schedules" ADD CONSTRAINT "schedules_internal_entity_id_fkey" FOREIGN KEY ("internal_entity_id") REFERENCES "public"."entities"("internal_id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user" ADD CONSTRAINT "user_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "public"."organizations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "vercel_resources" ADD CONSTRAINT "vercel_resources_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "account_userId_idx" ON "account" USING btree ("user_id");--> statement-breakpoint +CREATE INDEX "idx_actions_on_internal_entity_id" ON "actions" USING btree ("internal_entity_id");--> statement-breakpoint +CREATE UNIQUE INDEX "auto_topup_limits_org_env_internal_customer_feature_unique" ON "auto_topup_limit_states" USING btree ("org_id","env","internal_customer_id","feature_id");--> statement-breakpoint +CREATE INDEX "idx_checkouts_stripe_invoice_id" ON "checkouts" USING btree ("stripe_invoice_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_product_id" ON "customer_entitlements" USING btree ("customer_product_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_internal_customer_id" ON "customer_entitlements" USING hash ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_internal_customer_id_btree" ON "customer_entitlements" USING btree ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_entitlement_id" ON "customer_entitlements" USING btree ("entitlement_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_internal_entity_id" ON "customer_entitlements" USING hash ("internal_entity_id");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_on_next_reset_at" ON "customer_entitlements" USING btree ("next_reset_at");--> statement-breakpoint +CREATE INDEX "idx_customer_entitlements_loose_customer_expires" ON "customer_entitlements" USING btree ("internal_customer_id","expires_at") WHERE "customer_entitlements"."customer_product_id" IS NULL;--> statement-breakpoint +CREATE INDEX "idx_customer_prices_product_id" ON "customer_prices" USING btree ("customer_product_id");--> statement-breakpoint +CREATE INDEX "idx_customer_prices_price_id" ON "customer_prices" USING btree ("price_id");--> statement-breakpoint +CREATE INDEX "idx_customer_products_customer_status" ON "customer_products" USING btree ("internal_customer_id","status");--> statement-breakpoint +CREATE INDEX "idx_customer_products_on_internal_entity_id" ON "customer_products" USING btree ("internal_entity_id");--> statement-breakpoint +CREATE INDEX "idx_customer_products_on_internal_product_id" ON "customer_products" USING btree ("internal_product_id");--> statement-breakpoint +CREATE INDEX "idx_customer_products_subscription_ids" ON "customer_products" USING gin ("subscription_ids");--> statement-breakpoint +CREATE INDEX "idx_customer_products_scheduled_ids" ON "customer_products" USING gin ("scheduled_ids");--> statement-breakpoint +CREATE INDEX "idx_customer_products_stripe_checkout_session_id" ON "customer_products" USING btree ("stripe_checkout_session_id");--> statement-breakpoint +CREATE UNIQUE INDEX "customers_email_null_id_unique" ON "customers" USING btree ("org_id","env",lower("email")) WHERE "customers"."id" IS NULL AND "customers"."email" IS NOT NULL AND "customers"."email" != '';--> statement-breakpoint +CREATE INDEX "idx_customers_org_env_fingerprint" ON "customers" USING btree ("org_id","env","fingerprint") WHERE "customers"."fingerprint" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_customers_processor_id" ON "customers" USING btree (("processor" ->> 'id'));--> statement-breakpoint +CREATE INDEX "idx_customers_composite" ON "customers" USING btree ("org_id","env","id");--> statement-breakpoint +CREATE INDEX "idx_customers_org_env_internal_id" ON "customers" USING btree ("org_id","env","internal_id" DESC);--> statement-breakpoint +CREATE INDEX "idx_customers_email_trgm" ON "customers" USING gin ("email" gin_trgm_ops) WHERE "customers"."email" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_customers_name_trgm" ON "customers" USING gin ("name" gin_trgm_ops) WHERE "customers"."name" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_customers_id_trgm" ON "customers" USING gin ("id" gin_trgm_ops) WHERE "customers"."id" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_customers_org_id_env_created_at" ON "customers" USING btree ("org_id","env","created_at" DESC);--> statement-breakpoint +CREATE INDEX "idx_customers_processors_revenuecat" ON "customers" USING btree (("processors" ->> 'revenuecat'));--> statement-breakpoint +CREATE INDEX "idx_customers_processors_vercel" ON "customers" USING btree (("processors" ->> 'vercel'));--> statement-breakpoint +CREATE INDEX "idx_entities_internal_customer_id" ON "entities" USING btree ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_entities_customer_internal_desc" ON "entities" USING btree ("internal_customer_id","internal_id" DESC);--> statement-breakpoint +CREATE INDEX "idx_entities_org_env_id" ON "entities" USING btree ("org_id","env","id");--> statement-breakpoint +CREATE INDEX "idx_entitlements_internal_product_id" ON "entitlements" USING btree ("internal_product_id");--> statement-breakpoint +CREATE INDEX "idx_entitlements_internal_reward_id" ON "entitlements" USING btree ("internal_reward_id");--> statement-breakpoint +CREATE INDEX "idx_entitlements_reward_feature" ON "entitlements" USING btree ("internal_reward_id","internal_feature_id");--> statement-breakpoint +CREATE INDEX "idx_events_internal_customer_id" ON "events" USING btree ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_events_internal_entity_id" ON "events" USING btree ("internal_entity_id");--> statement-breakpoint +CREATE INDEX "idx_events_customer_non_usage_ts" ON "events" USING btree ("internal_customer_id","timestamp" DESC,"id" DESC) WHERE "events"."set_usage" = false;--> statement-breakpoint +CREATE INDEX "idx_free_trials_internal_product_id" ON "free_trials" USING btree ("internal_product_id");--> statement-breakpoint +CREATE INDEX "invitation_organizationId_idx" ON "invitation" USING btree ("organization_id");--> statement-breakpoint +CREATE INDEX "invitation_email_idx" ON "invitation" USING btree ("email");--> statement-breakpoint +CREATE INDEX "idx_invoices_customer_created" ON "invoices" USING btree ("internal_customer_id","created_at" DESC,"id" DESC);--> statement-breakpoint +CREATE INDEX "member_organizationId_idx" ON "member" USING btree ("organization_id");--> statement-breakpoint +CREATE INDEX "member_userId_idx" ON "member" USING btree ("user_id");--> statement-breakpoint +CREATE UNIQUE INDEX "migration_item_runs_live_unique" ON "migration_item_runs" USING btree ("migration_internal_id","item_kind","item_id") WHERE "migration_item_runs"."dry_run" = false;--> statement-breakpoint +CREATE UNIQUE INDEX "migration_item_runs_dry_run_unique" ON "migration_item_runs" USING btree ("migration_internal_id","migration_run_id","item_kind","item_id") WHERE "migration_item_runs"."dry_run" = true;--> statement-breakpoint +CREATE INDEX "migration_item_runs_customer_recent_idx" ON "migration_item_runs" USING btree ("item_id","updated_at" DESC) WHERE "migration_item_runs"."item_kind" = 'customer';--> statement-breakpoint +CREATE UNIQUE INDEX "migration_runs_active_per_migration_unique" ON "migration_runs" USING btree ("migration_internal_id") WHERE "migration_runs"."status" IN ('queued', 'running');--> statement-breakpoint +CREATE UNIQUE INDEX "migrations_org_env_id_unique" ON "migrations" USING btree ("org_id","env","id");--> statement-breakpoint +CREATE INDEX "idx_organizations_name_trgm" ON "organizations" USING gin ("name" gin_trgm_ops) WHERE "organizations"."name" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_organizations_slug_trgm" ON "organizations" USING gin ("slug" gin_trgm_ops) WHERE "organizations"."slug" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_organizations_created_at_id" ON "organizations" USING btree ("createdAt" DESC,"id" DESC);--> statement-breakpoint +CREATE INDEX "idx_prices_internal_product_id" ON "prices" USING btree ("internal_product_id");--> statement-breakpoint +CREATE INDEX "idx_prices_entitlement_id" ON "prices" USING btree ("entitlement_id");--> statement-breakpoint +CREATE INDEX "idx_products_org_env_id_version" ON "products" USING btree ("org_id","env","id","version");--> statement-breakpoint +CREATE INDEX "idx_referral_codes_internal_customer_id" ON "referral_codes" USING btree ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_replaceables_cus_ent_id" ON "replaceables" USING btree ("cus_ent_id");--> statement-breakpoint +CREATE INDEX "idx_reward_redemptions_referral_code_id" ON "reward_redemptions" USING btree ("referral_code_id");--> statement-breakpoint +CREATE INDEX "idx_reward_redemptions_reward_internal_id" ON "reward_redemptions" USING btree ("reward_internal_id");--> statement-breakpoint +CREATE INDEX "idx_reward_redemptions_customer_reward" ON "reward_redemptions" USING btree ("internal_customer_id","reward_internal_id");--> statement-breakpoint +CREATE INDEX "idx_rollovers_cus_ent_id" ON "rollovers" USING btree ("cus_ent_id");--> statement-breakpoint +CREATE INDEX "idx_rollovers_cus_ent_expires" ON "rollovers" USING btree ("cus_ent_id","expires_at");--> statement-breakpoint +CREATE UNIQUE INDEX "schedules_customer_scope_unique" ON "schedules" USING btree ("org_id","env","internal_customer_id") WHERE "schedules"."internal_entity_id" IS NULL;--> statement-breakpoint +CREATE UNIQUE INDEX "schedules_entity_scope_unique" ON "schedules" USING btree ("org_id","env","internal_customer_id","internal_entity_id") WHERE "schedules"."internal_entity_id" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_schedules_internal_customer_id" ON "schedules" USING btree ("internal_customer_id");--> statement-breakpoint +CREATE INDEX "idx_schedules_internal_entity_id" ON "schedules" USING btree ("internal_entity_id");--> statement-breakpoint +CREATE INDEX "session_userId_idx" ON "session" USING btree ("user_id");--> statement-breakpoint +CREATE INDEX "idx_user_name_trgm" ON "user" USING gin ("name" gin_trgm_ops) WHERE "user"."name" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_user_email_trgm" ON "user" USING gin ("email" gin_trgm_ops) WHERE "user"."email" IS NOT NULL;--> statement-breakpoint +CREATE INDEX "idx_user_created_at_id" ON "user" USING btree ("created_at" DESC,"id" DESC);--> statement-breakpoint +CREATE INDEX "verification_identifier_idx" ON "verification" USING btree ("identifier"); \ No newline at end of file diff --git a/shared/drizzle/meta/0000_snapshot.json b/shared/drizzle/meta/0000_snapshot.json new file mode 100644 index 000000000..5e40d909b --- /dev/null +++ b/shared/drizzle/meta/0000_snapshot.json @@ -0,0 +1,6667 @@ +{ + "id": "834b3759-eb80-411f-ba45-99c67cdc72db", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.actions": { + "name": "actions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_slug": { + "name": "org_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "properties": { + "name": "properties", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_actions_on_internal_entity_id": { + "name": "idx_actions_on_internal_entity_id", + "columns": [ + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "actions_org_id_fkey": { + "name": "actions_org_id_fkey", + "tableFrom": "actions", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "actions_customer_id_fkey": { + "name": "actions_customer_id_fkey", + "tableFrom": "actions", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "actions_entity_id_fkey": { + "name": "actions_entity_id_fkey", + "tableFrom": "actions", + "tableTo": "entities", + "columnsFrom": [ + "internal_entity_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.api_keys": { + "name": "api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hashed_key": { + "name": "hashed_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "meta": { + "name": "meta", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "api_keys_org_id_fkey": { + "name": "api_keys_org_id_fkey", + "tableFrom": "api_keys", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_hashed_key_key": { + "name": "api_keys_hashed_key_key", + "nullsNotDistinct": false, + "columns": [ + "hashed_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auto_topup_limit_states": { + "name": "auto_topup_limit_states", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "feature_id": { + "name": "feature_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "purchase_window_ends_at": { + "name": "purchase_window_ends_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "purchase_count": { + "name": "purchase_count", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "attempt_window_ends_at": { + "name": "attempt_window_ends_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "attempt_count": { + "name": "attempt_count", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed_attempt_window_ends_at": { + "name": "failed_attempt_window_ends_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "failed_attempt_count": { + "name": "failed_attempt_count", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_attempt_at": { + "name": "last_attempt_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "last_failed_attempt_at": { + "name": "last_failed_attempt_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + } + }, + "indexes": { + "auto_topup_limits_org_env_internal_customer_feature_unique": { + "name": "auto_topup_limits_org_env_internal_customer_feature_unique", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "feature_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_topup_limits_org_id_fkey": { + "name": "auto_topup_limits_org_id_fkey", + "tableFrom": "auto_topup_limit_states", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_topup_limits_internal_customer_id_fkey": { + "name": "auto_topup_limits_internal_customer_id_fkey", + "tableFrom": "auto_topup_limit_states", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chat_results": { + "name": "chat_results", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.checkouts": { + "name": "checkouts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "params": { + "name": "params", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "params_version": { + "name": "params_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "response": { + "name": "response", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "expires_at": { + "name": "expires_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "completed_at": { + "name": "completed_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_checkouts_stripe_invoice_id": { + "name": "idx_checkouts_stripe_invoice_id", + "columns": [ + { + "expression": "stripe_invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.customer_entitlements": { + "name": "customer_entitlements", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "customer_product_id": { + "name": "customer_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entitlement_id": { + "name": "entitlement_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text COLLATE \"C\"", + "primaryKey": false, + "notNull": true + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_feature_id": { + "name": "internal_feature_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "unlimited": { + "name": "unlimited", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "balance": { + "name": "balance", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "next_reset_at": { + "name": "next_reset_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "usage_allowed": { + "name": "usage_allowed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "adjustment": { + "name": "adjustment", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "additional_balance": { + "name": "additional_balance", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "entities": { + "name": "entities", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "cache_version": { + "name": "cache_version", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_customer_entitlements_product_id": { + "name": "idx_customer_entitlements_product_id", + "columns": [ + { + "expression": "customer_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_entitlements_internal_customer_id": { + "name": "idx_customer_entitlements_internal_customer_id", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + }, + "idx_customer_entitlements_internal_customer_id_btree": { + "name": "idx_customer_entitlements_internal_customer_id_btree", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_entitlements_entitlement_id": { + "name": "idx_customer_entitlements_entitlement_id", + "columns": [ + { + "expression": "entitlement_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_entitlements_internal_entity_id": { + "name": "idx_customer_entitlements_internal_entity_id", + "columns": [ + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + }, + "idx_customer_entitlements_on_next_reset_at": { + "name": "idx_customer_entitlements_on_next_reset_at", + "columns": [ + { + "expression": "next_reset_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_entitlements_loose_customer_expires": { + "name": "idx_customer_entitlements_loose_customer_expires", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"customer_entitlements\".\"customer_product_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "entitlements_internal_feature_id_fkey": { + "name": "entitlements_internal_feature_id_fkey", + "tableFrom": "customer_entitlements", + "tableTo": "features", + "columnsFrom": [ + "internal_feature_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "customer_entitlements_internal_entity_id_fkey": { + "name": "customer_entitlements_internal_entity_id_fkey", + "tableFrom": "customer_entitlements", + "tableTo": "entities", + "columnsFrom": [ + "internal_entity_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "customer_entitlements_customer_product_id_fkey": { + "name": "customer_entitlements_customer_product_id_fkey", + "tableFrom": "customer_entitlements", + "tableTo": "customer_products", + "columnsFrom": [ + "customer_product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "customer_entitlements_entitlement_id_fkey": { + "name": "customer_entitlements_entitlement_id_fkey", + "tableFrom": "customer_entitlements", + "tableTo": "entitlements", + "columnsFrom": [ + "entitlement_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.customer_prices": { + "name": "customer_prices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "price_id": { + "name": "price_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "options": { + "name": "options", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customer_product_id": { + "name": "customer_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_customer_prices_product_id": { + "name": "idx_customer_prices_product_id", + "columns": [ + { + "expression": "customer_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_prices_price_id": { + "name": "idx_customer_prices_price_id", + "columns": [ + { + "expression": "price_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "customer_prices_customer_product_id_fkey": { + "name": "customer_prices_customer_product_id_fkey", + "tableFrom": "customer_prices", + "tableTo": "customer_products", + "columnsFrom": [ + "customer_product_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "customer_prices_internal_customer_id_fkey": { + "name": "customer_prices_internal_customer_id_fkey", + "tableFrom": "customer_prices", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "customer_prices_price_id_fkey": { + "name": "customer_prices_price_id_fkey", + "tableFrom": "customer_prices", + "tableTo": "prices", + "columnsFrom": [ + "price_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.customer_products": { + "name": "customer_products", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "processor": { + "name": "processor", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "canceled": { + "name": "canceled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "ended_at": { + "name": "ended_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "starts_at": { + "name": "starts_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "access_starts_at": { + "name": "access_starts_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "options": { + "name": "options", + "type": "jsonb[]", + "primaryKey": false, + "notNull": false + }, + "product_id": { + "name": "product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "free_trial_id": { + "name": "free_trial_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "trial_ends_at": { + "name": "trial_ends_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "billing_cycle_anchor_resets_at": { + "name": "billing_cycle_anchor_resets_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "collection_method": { + "name": "collection_method", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'charge_automatically'" + }, + "subscription_ids": { + "name": "subscription_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "scheduled_ids": { + "name": "scheduled_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "is_custom": { + "name": "is_custom", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_version": { + "name": "billing_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_version": { + "name": "api_version", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "api_semver": { + "name": "api_semver", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_checkout_session_id": { + "name": "stripe_checkout_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_customer_product_id": { + "name": "previous_customer_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "on_trial_end": { + "name": "on_trial_end", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_customer_products_customer_status": { + "name": "idx_customer_products_customer_status", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_products_on_internal_entity_id": { + "name": "idx_customer_products_on_internal_entity_id", + "columns": [ + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_products_on_internal_product_id": { + "name": "idx_customer_products_on_internal_product_id", + "columns": [ + { + "expression": "internal_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customer_products_subscription_ids": { + "name": "idx_customer_products_subscription_ids", + "columns": [ + { + "expression": "subscription_ids", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_customer_products_scheduled_ids": { + "name": "idx_customer_products_scheduled_ids", + "columns": [ + { + "expression": "scheduled_ids", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_customer_products_stripe_checkout_session_id": { + "name": "idx_customer_products_stripe_checkout_session_id", + "columns": [ + { + "expression": "stripe_checkout_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "customer_products_free_trial_id_fkey": { + "name": "customer_products_free_trial_id_fkey", + "tableFrom": "customer_products", + "tableTo": "free_trials", + "columnsFrom": [ + "free_trial_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "customer_products_internal_customer_id_fkey": { + "name": "customer_products_internal_customer_id_fkey", + "tableFrom": "customer_products", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "customer_products_internal_product_id_fkey": { + "name": "customer_products_internal_product_id_fkey", + "tableFrom": "customer_products", + "tableTo": "products", + "columnsFrom": [ + "internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "customer_products_internal_entity_id_fkey": { + "name": "customer_products_internal_entity_id_fkey", + "tableFrom": "customer_products", + "tableTo": "entities", + "columnsFrom": [ + "internal_entity_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.customers": { + "name": "customers", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fingerprint": { + "name": "fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "processor": { + "name": "processor", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "processors": { + "name": "processors", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "send_email_receipts": { + "name": "send_email_receipts", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "auto_topups": { + "name": "auto_topups", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "spend_limits": { + "name": "spend_limits", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "usage_alerts": { + "name": "usage_alerts", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "overage_allowed": { + "name": "overage_allowed", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "customers_email_null_id_unique": { + "name": "customers_email_null_id_unique", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "lower(\"email\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"customers\".\"id\" IS NULL AND \"customers\".\"email\" IS NOT NULL AND \"customers\".\"email\" != ''", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_org_env_fingerprint": { + "name": "idx_customers_org_env_fingerprint", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"customers\".\"fingerprint\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_processor_id": { + "name": "idx_customers_processor_id", + "columns": [ + { + "expression": "(\"processor\" ->> 'id')", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_composite": { + "name": "idx_customers_composite", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_org_env_internal_id": { + "name": "idx_customers_org_env_internal_id", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"internal_id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_email_trgm": { + "name": "idx_customers_email_trgm", + "columns": [ + { + "expression": "\"email\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"customers\".\"email\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_customers_name_trgm": { + "name": "idx_customers_name_trgm", + "columns": [ + { + "expression": "\"name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"customers\".\"name\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_customers_id_trgm": { + "name": "idx_customers_id_trgm", + "columns": [ + { + "expression": "\"id\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"customers\".\"id\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_customers_org_id_env_created_at": { + "name": "idx_customers_org_id_env_created_at", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"created_at\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_processors_revenuecat": { + "name": "idx_customers_processors_revenuecat", + "columns": [ + { + "expression": "(\"processors\" ->> 'revenuecat')", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_customers_processors_vercel": { + "name": "idx_customers_processors_vercel", + "columns": [ + { + "expression": "(\"processors\" ->> 'vercel')", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "customers_org_id_fkey": { + "name": "customers_org_id_fkey", + "tableFrom": "customers", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "cus_id_constraint": { + "name": "cus_id_constraint", + "nullsNotDistinct": false, + "columns": [ + "org_id", + "id", + "env" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.entities": { + "name": "entities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted": { + "name": "deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "internal_feature_id": { + "name": "internal_feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "spend_limits": { + "name": "spend_limits", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "usage_alerts": { + "name": "usage_alerts", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "overage_allowed": { + "name": "overage_allowed", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_entities_internal_customer_id": { + "name": "idx_entities_internal_customer_id", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_entities_customer_internal_desc": { + "name": "idx_entities_customer_internal_desc", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"internal_id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_entities_org_env_id": { + "name": "idx_entities_org_env_id", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "entities_internal_customer_id_fkey": { + "name": "entities_internal_customer_id_fkey", + "tableFrom": "entities", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "entities_internal_feature_id_fkey": { + "name": "entities_internal_feature_id_fkey", + "tableFrom": "entities", + "tableTo": "features", + "columnsFrom": [ + "internal_feature_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "entities_org_id_fkey": { + "name": "entities_org_id_fkey", + "tableFrom": "entities", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "entity_id_constraint": { + "name": "entity_id_constraint", + "nullsNotDistinct": false, + "columns": [ + "org_id", + "env", + "internal_customer_id", + "id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.entitlements": { + "name": "entitlements", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "internal_feature_id": { + "name": "internal_feature_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_reward_id": { + "name": "internal_reward_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_custom": { + "name": "is_custom", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "allowance_type": { + "name": "allowance_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "allowance": { + "name": "allowance", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "interval": { + "name": "interval", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "interval_count": { + "name": "interval_count", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "carry_from_previous": { + "name": "carry_from_previous", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "entity_feature_id": { + "name": "entity_feature_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_limit": { + "name": "usage_limit", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "expiry_duration": { + "name": "expiry_duration", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expiry_length": { + "name": "expiry_length", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "rollover": { + "name": "rollover", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_entitlements_internal_product_id": { + "name": "idx_entitlements_internal_product_id", + "columns": [ + { + "expression": "internal_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_entitlements_internal_reward_id": { + "name": "idx_entitlements_internal_reward_id", + "columns": [ + { + "expression": "internal_reward_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_entitlements_reward_feature": { + "name": "idx_entitlements_reward_feature", + "columns": [ + { + "expression": "internal_reward_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "internal_feature_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "entitlements_internal_feature_id_fkey": { + "name": "entitlements_internal_feature_id_fkey", + "tableFrom": "entitlements", + "tableTo": "features", + "columnsFrom": [ + "internal_feature_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "entitlements_internal_product_id_fkey": { + "name": "entitlements_internal_product_id_fkey", + "tableFrom": "entitlements", + "tableTo": "products", + "columnsFrom": [ + "internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "entitlements_internal_reward_id_fkey": { + "name": "entitlements_internal_reward_id_fkey", + "tableFrom": "entitlements", + "tableTo": "rewards", + "columnsFrom": [ + "internal_reward_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "entitlements_id_key": { + "name": "entitlements_id_key", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_slug": { + "name": "org_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "event_name": { + "name": "event_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "value": { + "name": "value", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "set_usage": { + "name": "set_usage", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "properties": { + "name": "properties", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "deductions": { + "name": "deductions", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_events_internal_customer_id": { + "name": "idx_events_internal_customer_id", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_events_internal_entity_id": { + "name": "idx_events_internal_entity_id", + "columns": [ + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_events_customer_non_usage_ts": { + "name": "idx_events_customer_non_usage_ts", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"timestamp\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "\"id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"events\".\"set_usage\" = false", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "events_internal_customer_id_fkey": { + "name": "events_internal_customer_id_fkey", + "tableFrom": "events", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_event_constraint": { + "name": "unique_event_constraint", + "nullsNotDistinct": false, + "columns": [ + "org_id", + "env", + "customer_id", + "event_name", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.features": { + "name": "features", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "display": { + "name": "display", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "archived": { + "name": "archived", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "event_names": { + "name": "event_names", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + } + }, + "indexes": {}, + "foreignKeys": { + "features_org_id_fkey": { + "name": "features_org_id_fkey", + "tableFrom": "features", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "feature_id_constraint": { + "name": "feature_id_constraint", + "nullsNotDistinct": false, + "columns": [ + "org_id", + "id", + "env" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.free_trials": { + "name": "free_trials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duration": { + "name": "duration", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'day'" + }, + "length": { + "name": "length", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "unique_fingerprint": { + "name": "unique_fingerprint", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_custom": { + "name": "is_custom", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "card_required": { + "name": "card_required", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "on_end": { + "name": "on_end", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_free_trials_internal_product_id": { + "name": "idx_free_trials_internal_product_id", + "columns": [ + { + "expression": "internal_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "free_trials_internal_product_id_fkey": { + "name": "free_trials_internal_product_id_fkey", + "tableFrom": "free_trials", + "tableTo": "products", + "columnsFrom": [ + "internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "invitation_organizationId_idx": { + "name": "invitation_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "invitation_email_idx": { + "name": "invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invitation_organization_id_organizations_id_fk": { + "name": "invitation_organization_id_organizations_id_fk", + "tableFrom": "invitation", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invitation_inviter_id_user_id_fk": { + "name": "invitation_inviter_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.invoice_line_items": { + "name": "invoice_line_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_item_id": { + "name": "stripe_invoice_item_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_subscription_item_id": { + "name": "stripe_subscription_item_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_product_id": { + "name": "stripe_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_price_id": { + "name": "stripe_price_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_discountable": { + "name": "stripe_discountable", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "amount": { + "name": "amount", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "amount_after_discounts": { + "name": "amount_after_discounts", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'usd'" + }, + "stripe_quantity": { + "name": "stripe_quantity", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "total_quantity": { + "name": "total_quantity", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "paid_quantity": { + "name": "paid_quantity", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description_source": { + "name": "description_source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "direction": { + "name": "direction", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "billing_timing": { + "name": "billing_timing", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prorated": { + "name": "prorated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "price_id": { + "name": "price_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customer_product_ids": { + "name": "customer_product_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "customer_price_ids": { + "name": "customer_price_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "customer_entitlement_ids": { + "name": "customer_entitlement_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_id": { + "name": "product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "internal_feature_id": { + "name": "internal_feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "effective_period_start": { + "name": "effective_period_start", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "effective_period_end": { + "name": "effective_period_end", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "discounts": { + "name": "discounts", + "type": "jsonb[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + } + }, + "indexes": {}, + "foreignKeys": { + "invoice_line_items_invoice_id_fkey": { + "name": "invoice_line_items_invoice_id_fkey", + "tableFrom": "invoice_line_items", + "tableTo": "invoices", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "invoice_line_items_stripe_id_unique": { + "name": "invoice_line_items_stripe_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invoices": { + "name": "invoices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "product_ids": { + "name": "product_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "internal_product_ids": { + "name": "internal_product_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "processor_type": { + "name": "processor_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "hosted_invoice_url": { + "name": "hosted_invoice_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "total": { + "name": "total", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "amount_paid": { + "name": "amount_paid", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "refunded_amount": { + "name": "refunded_amount", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'usd'" + }, + "discounts": { + "name": "discounts", + "type": "jsonb[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "items": { + "name": "items", + "type": "jsonb[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + } + }, + "indexes": { + "idx_invoices_customer_created": { + "name": "idx_invoices_customer_created", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"created_at\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "\"id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invoices_internal_customer_id_fkey": { + "name": "invoices_internal_customer_id_fkey", + "tableFrom": "invoices", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invoices_internal_entity_id_fkey": { + "name": "invoices_internal_entity_id_fkey", + "tableFrom": "invoices", + "tableTo": "entities", + "columnsFrom": [ + "internal_entity_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "invoices_stripe_id_key": { + "name": "invoices_stripe_id_key", + "nullsNotDistinct": false, + "columns": [ + "stripe_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.jwks": { + "name": "jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.member": { + "name": "member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "member_organizationId_idx": { + "name": "member_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "member_userId_idx": { + "name": "member_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "member_organization_id_organizations_id_fk": { + "name": "member_organization_id_organizations_id_fk", + "tableFrom": "member", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_user_id_user_id_fk": { + "name": "member_user_id_user_id_fk", + "tableFrom": "member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.metadata": { + "name": "metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "expires_at": { + "name": "expires_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_checkout_session_id": { + "name": "stripe_checkout_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_errors": { + "name": "migration_errors", + "schema": "", + "columns": { + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "migration_job_id": { + "name": "migration_job_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "migration_customers_internal_customer_id_fkey": { + "name": "migration_customers_internal_customer_id_fkey", + "tableFrom": "migration_errors", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "migration_customers_migration_job_id_fkey": { + "name": "migration_customers_migration_job_id_fkey", + "tableFrom": "migration_errors", + "tableTo": "migration_jobs", + "columnsFrom": [ + "migration_job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "migration_errors_pkey": { + "name": "migration_errors_pkey", + "columns": [ + "internal_customer_id", + "migration_job_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_item_runs": { + "name": "migration_item_runs", + "schema": "", + "columns": { + "migration_item_run_id": { + "name": "migration_item_run_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "migration_internal_id": { + "name": "migration_internal_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "migration_run_id": { + "name": "migration_run_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "item_kind": { + "name": "item_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "item_id": { + "name": "item_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "migration_item_runs_live_unique": { + "name": "migration_item_runs_live_unique", + "columns": [ + { + "expression": "migration_internal_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"migration_item_runs\".\"dry_run\" = false", + "concurrently": false, + "method": "btree", + "with": {} + }, + "migration_item_runs_dry_run_unique": { + "name": "migration_item_runs_dry_run_unique", + "columns": [ + { + "expression": "migration_internal_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "migration_run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"migration_item_runs\".\"dry_run\" = true", + "concurrently": false, + "method": "btree", + "with": {} + }, + "migration_item_runs_customer_recent_idx": { + "name": "migration_item_runs_customer_recent_idx", + "columns": [ + { + "expression": "item_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "\"updated_at\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"migration_item_runs\".\"item_kind\" = 'customer'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_jobs": { + "name": "migration_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "current_step": { + "name": "current_step", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from_internal_product_id": { + "name": "from_internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "to_internal_product_id": { + "name": "to_internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "step_details": { + "name": "step_details", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "migration_jobs_from_internal_product_id_fkey": { + "name": "migration_jobs_from_internal_product_id_fkey", + "tableFrom": "migration_jobs", + "tableTo": "products", + "columnsFrom": [ + "from_internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "migration_jobs_org_id_fkey": { + "name": "migration_jobs_org_id_fkey", + "tableFrom": "migration_jobs", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "migration_jobs_to_internal_product_id_fkey": { + "name": "migration_jobs_to_internal_product_id_fkey", + "tableFrom": "migration_jobs", + "tableTo": "products", + "columnsFrom": [ + "to_internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_runs": { + "name": "migration_runs", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "migration_internal_id": { + "name": "migration_internal_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dry_run": { + "name": "dry_run", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "lazy_run": { + "name": "lazy_run", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "trigger_run_id": { + "name": "trigger_run_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "only_ids": { + "name": "only_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "migration_runs_active_per_migration_unique": { + "name": "migration_runs_active_per_migration_unique", + "columns": [ + { + "expression": "migration_internal_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"migration_runs\".\"status\" IN ('queued', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "migration_runs_migration_internal_id_fkey": { + "name": "migration_runs_migration_internal_id_fkey", + "tableFrom": "migration_runs", + "tableTo": "migrations", + "columnsFrom": [ + "migration_internal_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "migration_runs_org_id_fkey": { + "name": "migration_runs_org_id_fkey", + "tableFrom": "migration_runs", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migrations": { + "name": "migrations", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filter": { + "name": "filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "operations": { + "name": "operations", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "prepared_state": { + "name": "prepared_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "no_billing_changes": { + "name": "no_billing_changes", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "retry_failed": { + "name": "retry_failed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "migrations_org_env_id_unique": { + "name": "migrations_org_env_id_unique", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "migrations_org_id_fkey": { + "name": "migrations_org_id_fkey", + "tableFrom": "migrations", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.oauth_access_token": { + "name": "oauth_access_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_id": { + "name": "refresh_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_access_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_access_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_access_token_session_id_session_id_fk": { + "name": "oauth_access_token_session_id_session_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "oauth_access_token_user_id_user_id_fk": { + "name": "oauth_access_token_user_id_user_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_access_token_refresh_id_oauth_refresh_token_id_fk": { + "name": "oauth_access_token_refresh_id_oauth_refresh_token_id_fk", + "tableFrom": "oauth_access_token", + "tableTo": "oauth_refresh_token", + "columnsFrom": [ + "refresh_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_access_token_token_unique": { + "name": "oauth_access_token_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.oauth_client": { + "name": "oauth_client", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "skip_consent": { + "name": "skip_consent", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "enable_end_session": { + "name": "enable_end_session", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uri": { + "name": "uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contacts": { + "name": "contacts", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "tos": { + "name": "tos", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "policy": { + "name": "policy", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_id": { + "name": "software_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_version": { + "name": "software_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_statement": { + "name": "software_statement", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redirect_uris": { + "name": "redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "post_logout_redirect_uris": { + "name": "post_logout_redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "token_endpoint_auth_method": { + "name": "token_endpoint_auth_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_types": { + "name": "grant_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "response_types": { + "name": "response_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "public": { + "name": "public", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_client_user_id_user_id_fk": { + "name": "oauth_client_user_id_user_id_fk", + "tableFrom": "oauth_client", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_client_client_id_unique": { + "name": "oauth_client_client_id_unique", + "nullsNotDistinct": false, + "columns": [ + "client_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.oauth_consent": { + "name": "oauth_consent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_consent_client_id_oauth_client_client_id_fk": { + "name": "oauth_consent_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_consent", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_consent_user_id_user_id_fk": { + "name": "oauth_consent_user_id_user_id_fk", + "tableFrom": "oauth_consent", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.oauth_refresh_token": { + "name": "oauth_refresh_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked": { + "name": "revoked", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "oauth_refresh_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_refresh_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "oauth_client", + "columnsFrom": [ + "client_id" + ], + "columnsTo": [ + "client_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "oauth_refresh_token_session_id_session_id_fk": { + "name": "oauth_refresh_token_session_id_session_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "oauth_refresh_token_user_id_user_id_fk": { + "name": "oauth_refresh_token_user_id_user_id_fk", + "tableFrom": "oauth_refresh_token", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.organizations": { + "name": "organizations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_currency": { + "name": "default_currency", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'usd'" + }, + "stripe_connected": { + "name": "stripe_connected", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "stripe_config": { + "name": "stripe_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "test_stripe_connect": { + "name": "test_stripe_connect", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "live_stripe_connect": { + "name": "live_stripe_connect", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "processor_configs": { + "name": "processor_configs", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "test_pkey": { + "name": "test_pkey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "live_pkey": { + "name": "live_pkey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "svix_config": { + "name": "svix_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "onboarded": { + "name": "onboarded", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "deployed": { + "name": "deployed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "redis_config": { + "name": "redis_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_organizations_name_trgm": { + "name": "idx_organizations_name_trgm", + "columns": [ + { + "expression": "\"name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"organizations\".\"name\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_organizations_slug_trgm": { + "name": "idx_organizations_slug_trgm", + "columns": [ + { + "expression": "\"slug\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"organizations\".\"slug\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_organizations_created_at_id": { + "name": "idx_organizations_created_at_id", + "columns": [ + { + "expression": "\"createdAt\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "\"id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organizations_slug_unique": { + "name": "organizations_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + }, + "organizations_test_pkey_key": { + "name": "organizations_test_pkey_key", + "nullsNotDistinct": false, + "columns": [ + "test_pkey" + ] + }, + "organizations_live_pkey_key": { + "name": "organizations_live_pkey_key", + "nullsNotDistinct": false, + "columns": [ + "live_pkey" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.prices": { + "name": "prices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text COLLATE \"C\"", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_product_id": { + "name": "internal_product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "billing_type": { + "name": "billing_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tier_behavior": { + "name": "tier_behavior", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "is_custom": { + "name": "is_custom", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "entitlement_id": { + "name": "entitlement_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "proration_config": { + "name": "proration_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "null" + } + }, + "indexes": { + "idx_prices_internal_product_id": { + "name": "idx_prices_internal_product_id", + "columns": [ + { + "expression": "internal_product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_prices_entitlement_id": { + "name": "idx_prices_entitlement_id", + "columns": [ + { + "expression": "entitlement_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "prices_entitlement_id_fkey": { + "name": "prices_entitlement_id_fkey", + "tableFrom": "prices", + "tableTo": "entitlements", + "columnsFrom": [ + "entitlement_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "prices_internal_product_id_fkey": { + "name": "prices_internal_product_id_fkey", + "tableFrom": "prices", + "tableTo": "products", + "columnsFrom": [ + "internal_product_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "prices_id_key": { + "name": "prices_id_key", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.products": { + "name": "products", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_add_on": { + "name": "is_add_on", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "group": { + "name": "group", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "version": { + "name": "version", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "processor": { + "name": "processor", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "base_variant_id": { + "name": "base_variant_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived": { + "name": "archived", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "idx_products_org_env_id_version": { + "name": "idx_products_org_env_id_version", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "products_org_id_fkey": { + "name": "products_org_id_fkey", + "tableFrom": "products", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_product": { + "name": "unique_product", + "nullsNotDistinct": false, + "columns": [ + "org_id", + "id", + "env", + "version" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.referral_codes": { + "name": "referral_codes", + "schema": "", + "columns": { + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text COLLATE \"C\"", + "primaryKey": false, + "notNull": false + }, + "internal_reward_program_id": { + "name": "internal_reward_program_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_referral_codes_internal_customer_id": { + "name": "idx_referral_codes_internal_customer_id", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "referral_codes_internal_customer_id_fkey": { + "name": "referral_codes_internal_customer_id_fkey", + "tableFrom": "referral_codes", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "referral_codes_internal_reward_program_id_fkey": { + "name": "referral_codes_internal_reward_program_id_fkey", + "tableFrom": "referral_codes", + "tableTo": "reward_programs", + "columnsFrom": [ + "internal_reward_program_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "referral_codes_org_id_fkey": { + "name": "referral_codes_org_id_fkey", + "tableFrom": "referral_codes", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "referral_codes_pkey": { + "name": "referral_codes_pkey", + "columns": [ + "code", + "org_id", + "env" + ] + } + }, + "uniqueConstraints": { + "referral_codes_id_key": { + "name": "referral_codes_id_key", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.replaceables": { + "name": "replaceables", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "cus_ent_id": { + "name": "cus_ent_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "from_entity_id": { + "name": "from_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "delete_next_cycle": { + "name": "delete_next_cycle", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "idx_replaceables_cus_ent_id": { + "name": "idx_replaceables_cus_ent_id", + "columns": [ + { + "expression": "cus_ent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "replaceables_cus_ent_id_fkey": { + "name": "replaceables_cus_ent_id_fkey", + "tableFrom": "replaceables", + "tableTo": "customer_entitlements", + "columnsFrom": [ + "cus_ent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.revenuecat_mappings": { + "name": "revenuecat_mappings", + "schema": "", + "columns": { + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "autumn_product_id": { + "name": "autumn_product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "revenuecat_product_ids": { + "name": "revenuecat_product_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + } + }, + "indexes": {}, + "foreignKeys": { + "revenuecat_mappings_org_id_fkey": { + "name": "revenuecat_mappings_org_id_fkey", + "tableFrom": "revenuecat_mappings", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "revenuecat_mappings_pkey": { + "name": "revenuecat_mappings_pkey", + "columns": [ + "org_id", + "env", + "autumn_product_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reward_programs": { + "name": "reward_programs", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "internal_reward_id": { + "name": "internal_reward_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "max_redemptions": { + "name": "max_redemptions", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "unlimited_redemptions": { + "name": "unlimited_redemptions", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "when": { + "name": "when", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'immediately'" + }, + "product_ids": { + "name": "product_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{\"\"}'" + }, + "exclude_trial": { + "name": "exclude_trial", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "received_by": { + "name": "received_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reward_triggers_internal_reward_id_fkey": { + "name": "reward_triggers_internal_reward_id_fkey", + "tableFrom": "reward_programs", + "tableTo": "rewards", + "columnsFrom": [ + "internal_reward_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reward_triggers_org_id_fkey": { + "name": "reward_triggers_org_id_fkey", + "tableFrom": "reward_programs", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reward_redemptions": { + "name": "reward_redemptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text COLLATE \"C\"", + "primaryKey": false, + "notNull": false + }, + "triggered": { + "name": "triggered", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "internal_reward_program_id": { + "name": "internal_reward_program_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applied": { + "name": "applied", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "redeemer_applied": { + "name": "redeemer_applied", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "referral_code_id": { + "name": "referral_code_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reward_internal_id": { + "name": "reward_internal_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "promo_code": { + "name": "promo_code", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_reward_redemptions_referral_code_id": { + "name": "idx_reward_redemptions_referral_code_id", + "columns": [ + { + "expression": "referral_code_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reward_redemptions_reward_internal_id": { + "name": "idx_reward_redemptions_reward_internal_id", + "columns": [ + { + "expression": "reward_internal_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reward_redemptions_customer_reward": { + "name": "idx_reward_redemptions_customer_reward", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "reward_internal_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reward_redemptions_internal_customer_id_fkey": { + "name": "reward_redemptions_internal_customer_id_fkey", + "tableFrom": "reward_redemptions", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reward_redemptions_internal_reward_program_id_fkey": { + "name": "reward_redemptions_internal_reward_program_id_fkey", + "tableFrom": "reward_redemptions", + "tableTo": "reward_programs", + "columnsFrom": [ + "internal_reward_program_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reward_redemptions_referral_code_id_fkey": { + "name": "reward_redemptions_referral_code_id_fkey", + "tableFrom": "reward_redemptions", + "tableTo": "referral_codes", + "columnsFrom": [ + "referral_code_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.rewards": { + "name": "rewards", + "schema": "", + "columns": { + "internal_id": { + "name": "internal_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discount_config": { + "name": "discount_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "free_product_config": { + "name": "free_product_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "free_product_id": { + "name": "free_product_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "promo_codes": { + "name": "promo_codes", + "type": "jsonb[]", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "coupons_org_id_fkey": { + "name": "coupons_org_id_fkey", + "tableFrom": "rewards", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.rollovers": { + "name": "rollovers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "cus_ent_id": { + "name": "cus_ent_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "balance": { + "name": "balance", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "usage": { + "name": "usage", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "entities": { + "name": "entities", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "idx_rollovers_cus_ent_id": { + "name": "idx_rollovers_cus_ent_id", + "columns": [ + { + "expression": "cus_ent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_rollovers_cus_ent_expires": { + "name": "idx_rollovers_cus_ent_expires", + "columns": [ + { + "expression": "cus_ent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rollover_cus_ent_id_fkey": { + "name": "rollover_cus_ent_id_fkey", + "tableFrom": "rollovers", + "tableTo": "customer_entitlements", + "columnsFrom": [ + "cus_ent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.phases": { + "name": "phases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "starts_at": { + "name": "starts_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "customer_product_ids": { + "name": "customer_product_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "phases_schedule_id_fkey": { + "name": "phases_schedule_id_fkey", + "tableFrom": "phases", + "tableTo": "schedules", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "phases_schedule_id_starts_at_key": { + "name": "phases_schedule_id_starts_at_key", + "nullsNotDistinct": false, + "columns": [ + "schedule_id", + "starts_at" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.schedules": { + "name": "schedules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_customer_id": { + "name": "internal_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "customer_id": { + "name": "customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_entity_id": { + "name": "internal_entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "schedules_customer_scope_unique": { + "name": "schedules_customer_scope_unique", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"schedules\".\"internal_entity_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "schedules_entity_scope_unique": { + "name": "schedules_entity_scope_unique", + "columns": [ + { + "expression": "org_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "env", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"schedules\".\"internal_entity_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_schedules_internal_customer_id": { + "name": "idx_schedules_internal_customer_id", + "columns": [ + { + "expression": "internal_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_schedules_internal_entity_id": { + "name": "idx_schedules_internal_entity_id", + "columns": [ + { + "expression": "internal_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "schedules_org_id_fkey": { + "name": "schedules_org_id_fkey", + "tableFrom": "schedules", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "schedules_internal_customer_id_fkey": { + "name": "schedules_internal_customer_id_fkey", + "tableFrom": "schedules", + "tableTo": "customers", + "columnsFrom": [ + "internal_customer_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "schedules_internal_entity_id_fkey": { + "name": "schedules_internal_entity_id_fkey", + "tableFrom": "schedules", + "tableTo": "entities", + "columnsFrom": [ + "internal_entity_id" + ], + "columnsTo": [ + "internal_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "session_userId_idx": { + "name": "session_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.subscriptions": { + "name": "subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_schedule_id": { + "name": "stripe_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "ROUND(date_part('epoch', NOW()) * 1000)::BIGINT" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "usage_features": { + "name": "usage_features", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "current_period_start": { + "name": "current_period_start", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "current_period_end": { + "name": "current_period_end", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "subscriptions_org_id_fkey": { + "name": "subscriptions_org_id_fkey", + "tableFrom": "subscriptions", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "subscriptions_stripe_id_key": { + "name": "subscriptions_stripe_id_key", + "nullsNotDistinct": false, + "columns": [ + "stripe_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_active_at": { + "name": "last_active_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_user_name_trgm": { + "name": "idx_user_name_trgm", + "columns": [ + { + "expression": "\"name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"user\".\"name\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_user_email_trgm": { + "name": "idx_user_email_trgm", + "columns": [ + { + "expression": "\"email\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"user\".\"email\" IS NOT NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "idx_user_created_at_id": { + "name": "idx_user_created_at_id", + "columns": [ + { + "expression": "\"created_at\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "\"id\" DESC", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_created_by_fkey": { + "name": "user_created_by_fkey", + "tableFrom": "user", + "tableTo": "organizations", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vercel_resources": { + "name": "vercel_resources", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "installation_id": { + "name": "installation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": { + "vercel_resources_org_id_fkey": { + "name": "vercel_resources_org_id_fkey", + "tableFrom": "vercel_resources", + "tableTo": "organizations", + "columnsFrom": [ + "org_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "verification_identifier_idx": { + "name": "verification_identifier_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/drizzle/meta/_journal.json b/shared/drizzle/meta/_journal.json new file mode 100644 index 000000000..489f7bb0a --- /dev/null +++ b/shared/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1779096275848, + "tag": "0000_bumpy_tinkerer", + "breakpoints": true + } + ] +} \ No newline at end of file