From 6faee89b2554f162c1fa97dbe2a9598d25003590 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Fri, 19 Sep 2025 22:23:32 -0500 Subject: [PATCH] test(better auth): implementation start of better auth --- .env-example | 6 + .../app/auth/Auth Me.bru | 19 + .../app/auth/Register.bru | 24 + .../app/auth/Sign-In - email.bru | 35 + .../app/auth/Sign-In - username.bru | 35 + .../app/auth/folder.bru | 8 + LogisticsSupportTool_API_DOCS/app/folder.bru | 8 + .../app/system/Health.bru | 15 + .../app/system/folder.bru | 8 + .../environments/lst.bru | 4 + frontend/package-lock.json | 447 +++++++++- frontend/package.json | 2 + frontend/src/lib/authClient.ts | 11 + frontend/src/lib/utils.ts | 6 +- frontend/src/main.tsx | 9 +- frontend/src/routeTree.gen.ts | 214 ++++- frontend/src/routes/__admin.tsx | 9 + frontend/src/routes/__root.tsx | 7 +- .../routes/_adminLayout/-components/Nav.tsx | 23 + .../_adminLayout/-components/Server.tsx | 8 + .../src/routes/_adminLayout/admin/index.tsx | 9 + .../src/routes/_adminLayout/admin/servers.tsx | 27 + .../_adminLayout/admin/servers/$serverId.tsx | 10 + .../admin/servers/$serverId_/edit.tsx | 9 + .../_adminLayout/admin/user/$userId.tsx | 9 + .../src/routes/_adminLayout/admin/users.tsx | 9 + frontend/src/routes/_adminLayout/route.tsx | 16 + frontend/src/routes/admin_/settings.tsx | 9 + frontend/src/routes/index.tsx | 14 +- lstDocs/static/img/ocp/lotTransfer.png | Bin 54602 -> 57092 bytes migrations/0003_curved_mariko_yashida.sql | 90 ++ migrations/0004_panoramic_longshot.sql | 1 + migrations/0005_gorgeous_purple_man.sql | 9 + migrations/meta/0003_snapshot.json | 744 ++++++++++++++++ migrations/meta/0004_snapshot.json | 750 ++++++++++++++++ migrations/meta/0005_snapshot.json | 824 ++++++++++++++++++ migrations/meta/_journal.json | 21 + 37 files changed, 3433 insertions(+), 16 deletions(-) create mode 100644 LogisticsSupportTool_API_DOCS/app/auth/Auth Me.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/auth/Register.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/auth/Sign-In - email.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/auth/Sign-In - username.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/auth/folder.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/folder.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/system/Health.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/system/folder.bru create mode 100644 LogisticsSupportTool_API_DOCS/environments/lst.bru create mode 100644 frontend/src/lib/authClient.ts create mode 100644 frontend/src/routes/__admin.tsx create mode 100644 frontend/src/routes/_adminLayout/-components/Nav.tsx create mode 100644 frontend/src/routes/_adminLayout/-components/Server.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/index.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/servers.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/servers/$serverId.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/servers/$serverId_/edit.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/user/$userId.tsx create mode 100644 frontend/src/routes/_adminLayout/admin/users.tsx create mode 100644 frontend/src/routes/_adminLayout/route.tsx create mode 100644 frontend/src/routes/admin_/settings.tsx create mode 100644 migrations/0003_curved_mariko_yashida.sql create mode 100644 migrations/0004_panoramic_longshot.sql create mode 100644 migrations/0005_gorgeous_purple_man.sql create mode 100644 migrations/meta/0003_snapshot.json create mode 100644 migrations/meta/0004_snapshot.json create mode 100644 migrations/meta/0005_snapshot.json diff --git a/.env-example b/.env-example index cfea41c..fb68830 100644 --- a/.env-example +++ b/.env-example @@ -25,6 +25,12 @@ PROD_PLANT_TOKEN=test3 PROD_USER=alplaprod PROD_PASSWORD=password +# Auth stuff +BETTER_AUTH_SECRET="3d2b7d64ac2f9ebd6854325a84390666f4bbd2c7c3f537bb60fca3740f081e1e" + +# Your APP URL +BETTER_AUTH_URL="http://localhost:3000" + # Docker Related PROD_IP=10.193.0.56 LOGISTICS_NETWORK=10.193.14.0/24 diff --git a/LogisticsSupportTool_API_DOCS/app/auth/Auth Me.bru b/LogisticsSupportTool_API_DOCS/app/auth/Auth Me.bru new file mode 100644 index 0000000..6545d06 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/auth/Auth Me.bru @@ -0,0 +1,19 @@ +meta { + name: Auth Me + type: http + seq: 1 +} + +get { + url: http://{{url}}/lst/api/me + body: none + auth: inherit +} + +headers { + Cookie: {{session_cookie}} +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/auth/Register.bru b/LogisticsSupportTool_API_DOCS/app/auth/Register.bru new file mode 100644 index 0000000..915a845 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/auth/Register.bru @@ -0,0 +1,24 @@ +meta { + name: Register + type: http + seq: 2 +} + +post { + url: http://{{url}}/lst/api/register + body: json + auth: inherit +} + +body:json { + { + "username":"matthes01", + "name":"blake", + "email":"blake.matthes@alpla.com", + "password":"nova0511" + } +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - email.bru b/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - email.bru new file mode 100644 index 0000000..755d61c --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - email.bru @@ -0,0 +1,35 @@ +meta { + name: Sign-In - email + type: http + seq: 3 +} + +post { + url: http://{{url}}/lst/api/auth/sign-in/email + body: json + auth: inherit +} + +body:json { + { + "email": "blake.matthes@alpla.com", + "password": "nova0511" + } +} + +script:post-response { + // grab the raw Set-Cookie header + const cookies = res.headers["set-cookie"]; + + // cookies is usually an array, e.g. ["auth_session=abcd123; Path=/; HttpOnly; Secure; SameSite=Lax"] + + // Extract just the value part ("auth_session=abcd123") + const sessionCookie = cookies[0].split(";")[0]; + + // Save it as an environment variable + bru.setEnvVar("session_cookie", sessionCookie); +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - username.bru b/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - username.bru new file mode 100644 index 0000000..4e95f35 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/auth/Sign-In - username.bru @@ -0,0 +1,35 @@ +meta { + name: Sign-In - username + type: http + seq: 4 +} + +post { + url: http://{{url}}/lst/api/auth/sign-in/username + body: json + auth: inherit +} + +body:json { + { + "username": "matthes01", + "password": "nova0511" + } +} + +script:post-response { + // grab the raw Set-Cookie header + const cookies = res.headers["set-cookie"]; + + // cookies is usually an array, e.g. ["auth_session=abcd123; Path=/; HttpOnly; Secure; SameSite=Lax"] + + // Extract just the value part ("auth_session=abcd123") + const sessionCookie = cookies[0].split(";")[0]; + + // Save it as an environment variable + bru.setEnvVar("session_cookie", sessionCookie); +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/auth/folder.bru b/LogisticsSupportTool_API_DOCS/app/auth/folder.bru new file mode 100644 index 0000000..8fe9662 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/auth/folder.bru @@ -0,0 +1,8 @@ +meta { + name: auth + seq: 1 +} + +auth { + mode: inherit +} diff --git a/LogisticsSupportTool_API_DOCS/app/folder.bru b/LogisticsSupportTool_API_DOCS/app/folder.bru new file mode 100644 index 0000000..0b09462 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/folder.bru @@ -0,0 +1,8 @@ +meta { + name: app + seq: 2 +} + +auth { + mode: inherit +} diff --git a/LogisticsSupportTool_API_DOCS/app/system/Health.bru b/LogisticsSupportTool_API_DOCS/app/system/Health.bru new file mode 100644 index 0000000..b4c3af7 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/system/Health.bru @@ -0,0 +1,15 @@ +meta { + name: Health + type: http + seq: 1 +} + +get { + url: http://{{url}}/lst/api/system/health + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/system/folder.bru b/LogisticsSupportTool_API_DOCS/app/system/folder.bru new file mode 100644 index 0000000..9d9901f --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/system/folder.bru @@ -0,0 +1,8 @@ +meta { + name: system + seq: 2 +} + +auth { + mode: inherit +} diff --git a/LogisticsSupportTool_API_DOCS/environments/lst.bru b/LogisticsSupportTool_API_DOCS/environments/lst.bru new file mode 100644 index 0000000..347396f --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/environments/lst.bru @@ -0,0 +1,4 @@ +vars { + url: localhost:4200 + session_cookie: +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3e84ec6..74733f7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,8 +10,10 @@ "dependencies": { "@radix-ui/react-slot": "^1.2.3", "@tailwindcss/vite": "^4.1.13", + "@tanstack/react-query": "^5.89.0", "@tanstack/react-router": "^1.131.36", "@tanstack/react-router-devtools": "^1.131.36", + "better-auth": "^1.3.11", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.542.0", @@ -500,6 +502,17 @@ "node": ">=6.9.0" } }, + "node_modules/@better-auth/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==", + "license": "MIT" + }, + "node_modules/@better-fetch/fetch": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@better-fetch/fetch/-/fetch-1.1.18.tgz", + "integrity": "sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", @@ -1070,6 +1083,12 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@hexagon/base64": { + "version": "1.1.28", + "resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz", + "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==", + "license": "MIT" + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1193,6 +1212,36 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@levischuck/tiny-cbor": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz", + "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==", + "license": "MIT" + }, + "node_modules/@noble/ciphers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.0.0.tgz", + "integrity": "sha512-j/l6jpnpaIBM87cAYPJzi/6TgqmBv9spkqPyCXvRYsu5uxqh6tPJZDnD85yo8VWqzTuTQPgfv7NgT63u7kbwAQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.0.tgz", + "integrity": "sha512-h8VUBlE8R42+XIDO229cgisD287im3kdY6nbNZJFjc6ZvKIXPYXe6Vc/t+kyjFdMFyt5JpapzTsEg8n63w5/lw==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1231,6 +1280,162 @@ "node": ">= 8" } }, + "node_modules/@peculiar/asn1-android": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.5.0.tgz", + "integrity": "sha512-t8A83hgghWQkcneRsgGs2ebAlRe54ns88p7ouv8PW2tzF1nAW4yHcL4uZKrFpIU+uszIRzTkcCuie37gpkId0A==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.5.0.tgz", + "integrity": "sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "@peculiar/asn1-x509-attr": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.5.0.tgz", + "integrity": "sha512-ioigvA6WSYN9h/YssMmmoIwgl3RvZlAYx4A/9jD2qaqXZwGcNlAxaw54eSx2QG1Yu7YyBC5Rku3nNoHrQ16YsQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.5.0.tgz", + "integrity": "sha512-t4eYGNhXtLRxaP50h3sfO6aJebUCDGQACoeexcelL4roMFRRVgB20yBIu2LxsPh/tdW9I282gNgMOyg3ywg/mg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.5.0.tgz", + "integrity": "sha512-Vj0d0wxJZA+Ztqfb7W+/iu8Uasw6hhKtCdLKXLG/P3kEPIQpqGI4P4YXlROfl7gOCqFIbgsj1HzFIFwQ5s20ug==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-pkcs8": "^2.5.0", + "@peculiar/asn1-rsa": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.5.0.tgz", + "integrity": "sha512-L7599HTI2SLlitlpEP8oAPaJgYssByI4eCwQq2C9eC90otFpm8MRn66PpbKviweAlhinWQ3ZjDD2KIVtx7PaVw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.5.0.tgz", + "integrity": "sha512-UgqSMBLNLR5TzEZ5ZzxR45Nk6VJrammxd60WMSkofyNzd3DQLSNycGWSK5Xg3UTYbXcDFyG8pA/7/y/ztVCa6A==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-pfx": "^2.5.0", + "@peculiar/asn1-pkcs8": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "@peculiar/asn1-x509-attr": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.5.0.tgz", + "integrity": "sha512-qMZ/vweiTHy9syrkkqWFvbT3eLoedvamcUdnnvwyyUNv5FgFXA3KP8td+ATibnlZ0EANW5PYRm8E6MJzEB/72Q==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.5.0.tgz", + "integrity": "sha512-YM/nFfskFJSlHqv59ed6dZlLZqtZQwjRVJ4bBAiWV08Oc+1rSd5lDZcBEx0lGDHfSoH3UziI2pXt2UM33KerPQ==", + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.5.0.tgz", + "integrity": "sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.5.0.tgz", + "integrity": "sha512-9f0hPOxiJDoG/bfNLAFven+Bd4gwz/VzrCIIWc1025LEI4BXO0U5fOCTNDPbbp2ll+UzqKsZ3g61mpBp74gk9A==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.0.tgz", + "integrity": "sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-csr": "^2.5.0", + "@peculiar/asn1-ecc": "^2.5.0", + "@peculiar/asn1-pkcs9": "^2.5.0", + "@peculiar/asn1-rsa": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -1531,6 +1736,31 @@ "win32" ] }, + "node_modules/@simplewebauthn/browser": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.0.tgz", + "integrity": "sha512-N3fuA1AAnTo5gCStYoIoiasPccC+xPLx2YU88Dv0GeAmPQTWHETlZQq5xZ0DgUq1H9loXMWQH5qqUjcI7BHJ1A==", + "license": "MIT" + }, + "node_modules/@simplewebauthn/server": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.2.0.tgz", + "integrity": "sha512-meBOTUhWZsQyrBcXDva82Tiyes5UlPQu+fKuMKQlhmAJwR/a+orU8xYfpTQviEaV7qEYD4aMj9He/eBj1KX9hA==", + "license": "MIT", + "dependencies": { + "@hexagon/base64": "^1.1.27", + "@levischuck/tiny-cbor": "^0.2.2", + "@peculiar/asn1-android": "^2.3.10", + "@peculiar/asn1-ecc": "^2.3.8", + "@peculiar/asn1-rsa": "^2.3.8", + "@peculiar/asn1-schema": "^2.3.8", + "@peculiar/asn1-x509": "^2.3.8", + "@peculiar/x509": "^1.13.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@swc/core": { "version": "1.13.5", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", @@ -2032,6 +2262,32 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@tanstack/query-core": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.89.0.tgz", + "integrity": "sha512-joFV1MuPhSLsKfTzwjmPDrp8ENfZ9N23ymFu07nLfn3JCkSHy0CFgsyhHTJOmWaumC/WiNIKM0EJyduCF/Ih/Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.89.0.tgz", + "integrity": "sha512-SXbtWSTSRXyBOe80mszPxpEbaN4XPRUp/i0EfQK1uyj3KCk/c8FuPJNIRwzOVe/OU3rzxrYtiNabsAmk1l714A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.89.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@tanstack/react-router": { "version": "1.131.36", "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.131.36.tgz", @@ -2676,6 +2932,20 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asn1js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.6.tgz", + "integrity": "sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/ast-types": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", @@ -2709,6 +2979,83 @@ "dev": true, "license": "MIT" }, + "node_modules/better-auth": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/better-auth/-/better-auth-1.3.11.tgz", + "integrity": "sha512-7l8bHX5rnON4vsVmWB7g2UucNpRlXnDUX/n65mHeR3Zn2/lcpQvfBvGbTaHYU8UGCQadtJ7DLHW/zA3ZR7IfdA==", + "license": "MIT", + "dependencies": { + "@better-auth/utils": "0.3.0", + "@better-fetch/fetch": "^1.1.18", + "@noble/ciphers": "^2.0.0", + "@noble/hashes": "^2.0.0", + "@simplewebauthn/browser": "^13.1.2", + "@simplewebauthn/server": "^13.1.2", + "better-call": "1.0.19", + "defu": "^6.1.4", + "jose": "^6.1.0", + "kysely": "^0.28.5", + "nanostores": "^1.0.1", + "zod": "^4.1.5" + }, + "peerDependencies": { + "@lynx-js/react": "*", + "@sveltejs/kit": "^2.0.0", + "next": "^14.0.0 || ^15.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0", + "solid-js": "^1.0.0", + "svelte": "^4.0.0 || ^5.0.0", + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "@lynx-js/react": { + "optional": true + }, + "@sveltejs/kit": { + "optional": true + }, + "next": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "solid-js": { + "optional": true + }, + "svelte": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/better-auth/node_modules/zod": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.9.tgz", + "integrity": "sha512-HI32jTq0AUAC125z30E8bQNz0RQ+9Uc+4J7V97gLYjZVKRjeydPgGt6dvQzFrav7MYOUGFqqOGiHpA/fdbd0cQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/better-call": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/better-call/-/better-call-1.0.19.tgz", + "integrity": "sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw==", + "dependencies": { + "@better-auth/utils": "^0.3.0", + "@better-fetch/fetch": "^1.1.4", + "rou3": "^0.5.1", + "set-cookie-parser": "^2.7.1", + "uncrypto": "^0.1.3" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -2981,6 +3328,12 @@ "dev": true, "license": "MIT" }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -3604,6 +3957,15 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jose": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.0.tgz", + "integrity": "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3681,6 +4043,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kysely": { + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.7.tgz", + "integrity": "sha512-u/cAuTL4DRIiO2/g4vNGRgklEKNIj5Q3CG7RoUB5DV5SfEC2hMvPxKi0GWPmnzwL2ryIeud2VTcEEmqzTzEPNw==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4072,6 +4443,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nanostores": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.0.1.tgz", + "integrity": "sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": "^20.0.0 || >=22.0.0" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4262,6 +4648,24 @@ "node": ">=6" } }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4344,6 +4748,12 @@ "node": ">=0.10.0" } }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4414,6 +4824,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/rou3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.5.1.tgz", + "integrity": "sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==", + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4478,6 +4894,12 @@ "seroval": "^1.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4699,7 +5121,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "devOptional": true, "license": "0BSD" }, "node_modules/tsx": { @@ -4722,6 +5143,24 @@ "fsevents": "~2.3.3" } }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, "node_modules/tw-animate-css": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.8.tgz", @@ -4783,6 +5222,12 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0c207d6..fcffa85 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,8 +12,10 @@ "dependencies": { "@radix-ui/react-slot": "^1.2.3", "@tailwindcss/vite": "^4.1.13", + "@tanstack/react-query": "^5.89.0", "@tanstack/react-router": "^1.131.36", "@tanstack/react-router-devtools": "^1.131.36", + "better-auth": "^1.3.11", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.542.0", diff --git a/frontend/src/lib/authClient.ts b/frontend/src/lib/authClient.ts new file mode 100644 index 0000000..5f137da --- /dev/null +++ b/frontend/src/lib/authClient.ts @@ -0,0 +1,11 @@ +import { createAuthClient } from "better-auth/client"; +import { usernameClient } from "better-auth/client/plugins"; +export const authClient = createAuthClient({ + baseURL: `${window.location.origin}/lst/api/auth`, // 👈 This is fine + callbacks: { + onUpdate: (session: any) => console.log("Session updated", session), + onSignIn: (session: any) => console.log("Signed in!", session), + onSignOut: () => console.log("Signed out!"), + }, + plugins: [usernameClient()], +}); diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index bd0c391..e6a8be0 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -1,6 +1,6 @@ -import { clsx, type ClassValue } from "clsx" -import { twMerge } from "tailwind-merge" +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) + return twMerge(clsx(inputs)); } diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 3287e7f..7d21636 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,12 +1,15 @@ import { StrictMode } from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; - import { RouterProvider, createRouter } from "@tanstack/react-router"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; // Import the generated route tree import { routeTree } from "./routeTree.gen"; +// Create a client +const queryClient = new QueryClient(); + // Create a new router instance const router = createRouter({ routeTree, basepath: "/lst/app" }); @@ -19,6 +22,8 @@ declare module "@tanstack/react-router" { ReactDOM.createRoot(document.getElementById("root")!).render( - + + + ); diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index d204c26..6dea534 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -9,38 +9,160 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' +import { Route as _adminRouteImport } from './routes/__admin' +import { Route as AdminLayoutRouteRouteImport } from './routes/_adminLayout/route' import { Route as IndexRouteImport } from './routes/index' +import { Route as AdminSettingsRouteImport } from './routes/admin_/settings' +import { Route as AdminLayoutAdminIndexRouteImport } from './routes/_adminLayout/admin/index' +import { Route as AdminLayoutAdminUsersRouteImport } from './routes/_adminLayout/admin/users' +import { Route as AdminLayoutAdminServersRouteImport } from './routes/_adminLayout/admin/servers' +import { Route as AdminLayoutAdminUserUserIdRouteImport } from './routes/_adminLayout/admin/user/$userId' +import { Route as AdminLayoutAdminServersServerIdRouteImport } from './routes/_adminLayout/admin/servers/$serverId' +import { Route as AdminLayoutAdminServersServerIdEditRouteImport } from './routes/_adminLayout/admin/servers/$serverId_/edit' +const _adminRoute = _adminRouteImport.update({ + id: '/__admin', + getParentRoute: () => rootRouteImport, +} as any) +const AdminLayoutRouteRoute = AdminLayoutRouteRouteImport.update({ + id: '/_adminLayout', + getParentRoute: () => rootRouteImport, +} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => rootRouteImport, } as any) +const AdminSettingsRoute = AdminSettingsRouteImport.update({ + id: '/admin_/settings', + path: '/admin/settings', + getParentRoute: () => rootRouteImport, +} as any) +const AdminLayoutAdminIndexRoute = AdminLayoutAdminIndexRouteImport.update({ + id: '/admin/', + path: '/admin/', + getParentRoute: () => AdminLayoutRouteRoute, +} as any) +const AdminLayoutAdminUsersRoute = AdminLayoutAdminUsersRouteImport.update({ + id: '/admin/users', + path: '/admin/users', + getParentRoute: () => AdminLayoutRouteRoute, +} as any) +const AdminLayoutAdminServersRoute = AdminLayoutAdminServersRouteImport.update({ + id: '/admin/servers', + path: '/admin/servers', + getParentRoute: () => AdminLayoutRouteRoute, +} as any) +const AdminLayoutAdminUserUserIdRoute = + AdminLayoutAdminUserUserIdRouteImport.update({ + id: '/admin/user/$userId', + path: '/admin/user/$userId', + getParentRoute: () => AdminLayoutRouteRoute, + } as any) +const AdminLayoutAdminServersServerIdRoute = + AdminLayoutAdminServersServerIdRouteImport.update({ + id: '/$serverId', + path: '/$serverId', + getParentRoute: () => AdminLayoutAdminServersRoute, + } as any) +const AdminLayoutAdminServersServerIdEditRoute = + AdminLayoutAdminServersServerIdEditRouteImport.update({ + id: '/$serverId_/edit', + path: '/$serverId/edit', + getParentRoute: () => AdminLayoutAdminServersRoute, + } as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute + '/admin/settings': typeof AdminSettingsRoute + '/admin/servers': typeof AdminLayoutAdminServersRouteWithChildren + '/admin/users': typeof AdminLayoutAdminUsersRoute + '/admin': typeof AdminLayoutAdminIndexRoute + '/admin/servers/$serverId': typeof AdminLayoutAdminServersServerIdRoute + '/admin/user/$userId': typeof AdminLayoutAdminUserUserIdRoute + '/admin/servers/$serverId/edit': typeof AdminLayoutAdminServersServerIdEditRoute } export interface FileRoutesByTo { '/': typeof IndexRoute + '/admin/settings': typeof AdminSettingsRoute + '/admin/servers': typeof AdminLayoutAdminServersRouteWithChildren + '/admin/users': typeof AdminLayoutAdminUsersRoute + '/admin': typeof AdminLayoutAdminIndexRoute + '/admin/servers/$serverId': typeof AdminLayoutAdminServersServerIdRoute + '/admin/user/$userId': typeof AdminLayoutAdminUserUserIdRoute + '/admin/servers/$serverId/edit': typeof AdminLayoutAdminServersServerIdEditRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/': typeof IndexRoute + '/_adminLayout': typeof AdminLayoutRouteRouteWithChildren + '/__admin': typeof _adminRoute + '/admin_/settings': typeof AdminSettingsRoute + '/_adminLayout/admin/servers': typeof AdminLayoutAdminServersRouteWithChildren + '/_adminLayout/admin/users': typeof AdminLayoutAdminUsersRoute + '/_adminLayout/admin/': typeof AdminLayoutAdminIndexRoute + '/_adminLayout/admin/servers/$serverId': typeof AdminLayoutAdminServersServerIdRoute + '/_adminLayout/admin/user/$userId': typeof AdminLayoutAdminUserUserIdRoute + '/_adminLayout/admin/servers/$serverId_/edit': typeof AdminLayoutAdminServersServerIdEditRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' + fullPaths: + | '/' + | '/admin/settings' + | '/admin/servers' + | '/admin/users' + | '/admin' + | '/admin/servers/$serverId' + | '/admin/user/$userId' + | '/admin/servers/$serverId/edit' fileRoutesByTo: FileRoutesByTo - to: '/' - id: '__root__' | '/' + to: + | '/' + | '/admin/settings' + | '/admin/servers' + | '/admin/users' + | '/admin' + | '/admin/servers/$serverId' + | '/admin/user/$userId' + | '/admin/servers/$serverId/edit' + id: + | '__root__' + | '/' + | '/_adminLayout' + | '/__admin' + | '/admin_/settings' + | '/_adminLayout/admin/servers' + | '/_adminLayout/admin/users' + | '/_adminLayout/admin/' + | '/_adminLayout/admin/servers/$serverId' + | '/_adminLayout/admin/user/$userId' + | '/_adminLayout/admin/servers/$serverId_/edit' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute + AdminLayoutRouteRoute: typeof AdminLayoutRouteRouteWithChildren + _adminRoute: typeof _adminRoute + AdminSettingsRoute: typeof AdminSettingsRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { + '/__admin': { + id: '/__admin' + path: '' + fullPath: '' + preLoaderRoute: typeof _adminRouteImport + parentRoute: typeof rootRouteImport + } + '/_adminLayout': { + id: '/_adminLayout' + path: '' + fullPath: '' + preLoaderRoute: typeof AdminLayoutRouteRouteImport + parentRoute: typeof rootRouteImport + } '/': { id: '/' path: '/' @@ -48,11 +170,97 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } + '/admin_/settings': { + id: '/admin_/settings' + path: '/admin/settings' + fullPath: '/admin/settings' + preLoaderRoute: typeof AdminSettingsRouteImport + parentRoute: typeof rootRouteImport + } + '/_adminLayout/admin/': { + id: '/_adminLayout/admin/' + path: '/admin' + fullPath: '/admin' + preLoaderRoute: typeof AdminLayoutAdminIndexRouteImport + parentRoute: typeof AdminLayoutRouteRoute + } + '/_adminLayout/admin/users': { + id: '/_adminLayout/admin/users' + path: '/admin/users' + fullPath: '/admin/users' + preLoaderRoute: typeof AdminLayoutAdminUsersRouteImport + parentRoute: typeof AdminLayoutRouteRoute + } + '/_adminLayout/admin/servers': { + id: '/_adminLayout/admin/servers' + path: '/admin/servers' + fullPath: '/admin/servers' + preLoaderRoute: typeof AdminLayoutAdminServersRouteImport + parentRoute: typeof AdminLayoutRouteRoute + } + '/_adminLayout/admin/user/$userId': { + id: '/_adminLayout/admin/user/$userId' + path: '/admin/user/$userId' + fullPath: '/admin/user/$userId' + preLoaderRoute: typeof AdminLayoutAdminUserUserIdRouteImport + parentRoute: typeof AdminLayoutRouteRoute + } + '/_adminLayout/admin/servers/$serverId': { + id: '/_adminLayout/admin/servers/$serverId' + path: '/$serverId' + fullPath: '/admin/servers/$serverId' + preLoaderRoute: typeof AdminLayoutAdminServersServerIdRouteImport + parentRoute: typeof AdminLayoutAdminServersRoute + } + '/_adminLayout/admin/servers/$serverId_/edit': { + id: '/_adminLayout/admin/servers/$serverId_/edit' + path: '/$serverId/edit' + fullPath: '/admin/servers/$serverId/edit' + preLoaderRoute: typeof AdminLayoutAdminServersServerIdEditRouteImport + parentRoute: typeof AdminLayoutAdminServersRoute + } } } +interface AdminLayoutAdminServersRouteChildren { + AdminLayoutAdminServersServerIdRoute: typeof AdminLayoutAdminServersServerIdRoute + AdminLayoutAdminServersServerIdEditRoute: typeof AdminLayoutAdminServersServerIdEditRoute +} + +const AdminLayoutAdminServersRouteChildren: AdminLayoutAdminServersRouteChildren = + { + AdminLayoutAdminServersServerIdRoute: AdminLayoutAdminServersServerIdRoute, + AdminLayoutAdminServersServerIdEditRoute: + AdminLayoutAdminServersServerIdEditRoute, + } + +const AdminLayoutAdminServersRouteWithChildren = + AdminLayoutAdminServersRoute._addFileChildren( + AdminLayoutAdminServersRouteChildren, + ) + +interface AdminLayoutRouteRouteChildren { + AdminLayoutAdminServersRoute: typeof AdminLayoutAdminServersRouteWithChildren + AdminLayoutAdminUsersRoute: typeof AdminLayoutAdminUsersRoute + AdminLayoutAdminIndexRoute: typeof AdminLayoutAdminIndexRoute + AdminLayoutAdminUserUserIdRoute: typeof AdminLayoutAdminUserUserIdRoute +} + +const AdminLayoutRouteRouteChildren: AdminLayoutRouteRouteChildren = { + AdminLayoutAdminServersRoute: AdminLayoutAdminServersRouteWithChildren, + AdminLayoutAdminUsersRoute: AdminLayoutAdminUsersRoute, + AdminLayoutAdminIndexRoute: AdminLayoutAdminIndexRoute, + AdminLayoutAdminUserUserIdRoute: AdminLayoutAdminUserUserIdRoute, +} + +const AdminLayoutRouteRouteWithChildren = + AdminLayoutRouteRoute._addFileChildren(AdminLayoutRouteRouteChildren) + const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, + AdminLayoutRouteRoute: AdminLayoutRouteRouteWithChildren, + _adminRoute: _adminRoute, + AdminSettingsRoute: AdminSettingsRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/frontend/src/routes/__admin.tsx b/frontend/src/routes/__admin.tsx new file mode 100644 index 0000000..a091070 --- /dev/null +++ b/frontend/src/routes/__admin.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/__admin')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/(__admin)/__admin"!
+} diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index ad88135..c4fcdf0 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -1,8 +1,13 @@ -import { createRootRoute, Outlet } from "@tanstack/react-router"; +import { createRootRoute, Link, Outlet } from "@tanstack/react-router"; import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; const RootLayout = () => ( <> + +
diff --git a/frontend/src/routes/_adminLayout/-components/Nav.tsx b/frontend/src/routes/_adminLayout/-components/Nav.tsx new file mode 100644 index 0000000..cbe9704 --- /dev/null +++ b/frontend/src/routes/_adminLayout/-components/Nav.tsx @@ -0,0 +1,23 @@ +import { Link } from "@tanstack/react-router"; + +export default function Nav() { + return ( +
+ +
+ ); +} diff --git a/frontend/src/routes/_adminLayout/-components/Server.tsx b/frontend/src/routes/_adminLayout/-components/Server.tsx new file mode 100644 index 0000000..e7a95e3 --- /dev/null +++ b/frontend/src/routes/_adminLayout/-components/Server.tsx @@ -0,0 +1,8 @@ +import { getRouteApi } from "@tanstack/react-router"; + +export default function Server() { + const { useParams } = getRouteApi("/_adminLayout/admin/servers/$serverId"); + + const { serverId } = useParams(); + return
server id {serverId}!
; +} diff --git a/frontend/src/routes/_adminLayout/admin/index.tsx b/frontend/src/routes/_adminLayout/admin/index.tsx new file mode 100644 index 0000000..94c2ed8 --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/index.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/_adminLayout/admin/')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/_adminLayout/admin/"!
+} diff --git a/frontend/src/routes/_adminLayout/admin/servers.tsx b/frontend/src/routes/_adminLayout/admin/servers.tsx new file mode 100644 index 0000000..33a05e6 --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/servers.tsx @@ -0,0 +1,27 @@ +import { createFileRoute, Link } from "@tanstack/react-router"; + +export const Route = createFileRoute("/_adminLayout/admin/servers")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ( +
+ Hello "/admin/servers"!
+ + Server 5 + + ({ ...prev, serverId: "10" })} + > + Server 5 + +
+ ); +} diff --git a/frontend/src/routes/_adminLayout/admin/servers/$serverId.tsx b/frontend/src/routes/_adminLayout/admin/servers/$serverId.tsx new file mode 100644 index 0000000..ecf74f4 --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/servers/$serverId.tsx @@ -0,0 +1,10 @@ +import { createFileRoute } from "@tanstack/react-router"; +import Server from "../../-components/Server"; + +export const Route = createFileRoute("/_adminLayout/admin/servers/$serverId")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ; +} diff --git a/frontend/src/routes/_adminLayout/admin/servers/$serverId_/edit.tsx b/frontend/src/routes/_adminLayout/admin/servers/$serverId_/edit.tsx new file mode 100644 index 0000000..fb5d993 --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/servers/$serverId_/edit.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/_adminLayout/admin/servers/$serverId_/edit')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/_adminLayout/admin/_server/$edit"!
+} diff --git a/frontend/src/routes/_adminLayout/admin/user/$userId.tsx b/frontend/src/routes/_adminLayout/admin/user/$userId.tsx new file mode 100644 index 0000000..87d048c --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/user/$userId.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/_adminLayout/admin/user/$userId')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/_adminLayout/admin/$userId"!
+} diff --git a/frontend/src/routes/_adminLayout/admin/users.tsx b/frontend/src/routes/_adminLayout/admin/users.tsx new file mode 100644 index 0000000..53d1be4 --- /dev/null +++ b/frontend/src/routes/_adminLayout/admin/users.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/_adminLayout/admin/users')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/admin/users"!
+} diff --git a/frontend/src/routes/_adminLayout/route.tsx b/frontend/src/routes/_adminLayout/route.tsx new file mode 100644 index 0000000..9886c34 --- /dev/null +++ b/frontend/src/routes/_adminLayout/route.tsx @@ -0,0 +1,16 @@ +import { createFileRoute, Outlet } from "@tanstack/react-router"; +import Nav from "./-components/Nav"; + +export const Route = createFileRoute("/_adminLayout")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ( +
+
+ ); +} diff --git a/frontend/src/routes/admin_/settings.tsx b/frontend/src/routes/admin_/settings.tsx new file mode 100644 index 0000000..9101dfa --- /dev/null +++ b/frontend/src/routes/admin_/settings.tsx @@ -0,0 +1,9 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/admin_/settings')({ + component: RouteComponent, +}) + +function RouteComponent() { + return
Hello "/admin_/settings"!
+} diff --git a/frontend/src/routes/index.tsx b/frontend/src/routes/index.tsx index d617d4a..da865ef 100644 --- a/frontend/src/routes/index.tsx +++ b/frontend/src/routes/index.tsx @@ -7,12 +7,14 @@ export const Route = createFileRoute("/")({ function Index() { return ( -
- +
+
); } diff --git a/lstDocs/static/img/ocp/lotTransfer.png b/lstDocs/static/img/ocp/lotTransfer.png index aebdee7de4587547eb23266d114fe8cc84260ef6..d0358c141837f2866a77d748f19ae78076571819 100644 GIT binary patch literal 57092 zcmeFZcT|(v*FTCnRz$`TK}EneAW9LHUNRO$gn)ty2m}EUsR5}WB(YFNP!N$K0isA# z1f+$Q5T#0u(n3w7MhGF003iuUeh;Yg&UfB+a@9+B4&K?yoHF!CPfjE^&(p~0l#5S#X12WzqpxOe5@Ate{-O-u+tH1o=6Qzc=%*&4t|2}E$Q|*F3+gh9;d*jiW zeYJz#(ULpp^@k2CW_+DHTx?h_*3z!!l`{yAQl5Y9hO8hjcHbytTbk>a^$s{tQ}Jx! z=I8bJ!2BDFMb~=@-jaDZg@xro0)KE18NnW&>(FJ?&n*o?cWwD){rx`<{Q4gsw+_+| ze@Z_);IL=Z+v3}kt;WkH!o`L;6rWcZVJmER9zk)WFybgGMsPitD4a+C%Mia}^**KF zpON__`(Wnx)v-!1N=vHu%Nq{#KaD?f-&_z0jS$kMP?{_JSdgSa;C%mFJw_1gvseuc z3nI&q`G9D@KWOu%?Y9_zEd6>*^~{pQE$Er0J+}&9G0?l?!BM5!2X&=|9HQXlZ19k8 zAV_{yb!*Rw#2MvJvJYp}Kc%0e+wS&_KZ}BomJfqaQ2{404EHA3t;Z{h4(?8xxI}WN(Qd;xBaF zia#5uL=I)OFIQh)so(XpgZ0M#hfnca`r|KBvV&to%SK5^M&(eZ`=g)gZ|z4v#UMh6QW)gHRdMy=#eTm2UZ+^$Abc0oD~i2> z!3fPqoTV^y^7^06)-wI^Pw|h+$sxya)JWmtM&$I?pKberNdawWO=tvrg~(nBtl$o7 zR+ay37P)S;bmSIv^ob^U3xlI8Tqv*AWeB|3l0Q3qnEsR=HUq{9xU>;{1_y*J(cS*D z?R`kG=KO$1VUh7)lG-7OmiXEH_3|fjeO_Tri~Q;iT6?stJ%R1^{keDUgX z=?gRPQ{;V>WR2ygWewL||L66B8fivzrj|Hz>YMM)^FuX-e`LdMy5>l)vii1f$_8G@{<{=3-5I-K~et&#uD-M;yFLbM>>k zN<`~h`!bVN2F#fTHW#6kR_0B~erH){nHLouPN7%Q3%tG3j6cIlsr^hd=I4aMB|isp zz!3A6FH_@<8?npFjdhulnM*lkpEdvvpC$KKe;X$r;tz7vUuDxIQJNrqbw!N$-PJ4t~YSLwN5}&VX3;>}UmKk9UC= zlcI7PtyQ8V$@a9E(SWtYmcv?N0;n_^SgQP5&D;65TDIFY15K#e3lBGwG@WQh78bXp zqXzOl2%)Okqm~CZz&NS!gEFlHhbKBBWK;WIbmSGTXx zB`hGlkfx1az2kb|lrJjxsL>SPbtJ$am+r1UI;0|)6s^s$s}GWhu5TU8oD+l-niBEt z>`!;u_I0hcSx-FedzfGIJT2;%Sksh2yQ915qzS};hMCS`#@@8R6{sI5k!_d;hG*X; z`uvAves?&kB4tw&&TLs<@#lOBJNuwR{i5U$-nmuTVE94SR<}VEmcfken zAJ?NLP9>nf+o9T;*?hgID0yws32T2dUpcDv5bj24zKVgXXm!U~q+~WV7Lq*6q{`Sf z$cNjPN~smfBdR~iu=Jhc4|PhbEbUi-PH~aRSQlk+gF@WIrU#RW4Rd3qB=@c|(jFA? zygk3dONN35Y_;*9tIe`InyxZB*s$nyWyt1;6nWIov{h*)q)D$Vm=ka;y2()1s>0Z@ zCjV()$YV~R#ui)%dRmeZy>U)YuB4o4twC~ZWY zf2pZh)gB(Mskkrj<6x_;%j^2L6CbHb<>{1`h`29SLFZ@ix!NvJeA4C4GTvreT{0o{9O26^42xs=&x$5w;eWGbU?#w`W8>cg&)W9?{~P{4 zE0TszO+~>HRG7Gmc|G>*hzjyr#lQQ9eJmW&#ncQ7?A$SIgd zFW(9PU7xUX(}h_K$mG{i$5dd9u*I#9#s31puOt)o9jt@n&zc`S^3Z`>s2U-pQBdkb zT&S$5u$8bJy1a^{Mh#ctwvYdVh4xM(69;7kc464&t51pX)^f*_o4s%=s+kWOFj67DQOvY*U#ROj)mtVHf{ zE>e^br3*cst|k;^M8(2HXHL$27xG8L6J{bGxQ?N#Ti|lZTTZPVTEflZpze|HC^~f& zMc>{b@;*INJgLTx>pwLp)xXg-Rpeg#$K};`Uf$lz3V)%g*jaxz@B)(Oku++h*P+i* z7_Jt%7odQsTA+6}(d_4n_9%$lJf&u^`bw_Nt(p^E^5JRLE9P=sFG0^P5zhltgITed zfSZo1BRBpSnarteLrYBM^%ozntzR#qk+d-1Ny;gleqtZy^!I-0oZ4^TZN{d725Wem zXA!C{Euw*0SnQ;lP(Y=;cCB?HgAeCd9nv4|O011)A@OH_i!Z#hGQiN668^eLb1x{uY(A}<8>z`yCq+(%7Ay`yA1ZGs2+KUmbhCS zDl?W}PTnS@QiYbweGRVFK_Vi9XSv9|8*V8*RXZcD^mv!Zd;A``)fsg!v`dvHq%J^hzIP)348 z#{nWX{@b8wKL+id6iumj1R%_bT#ejSTMKmlZfllk)jPkrcFP++t{(^He0|@EAJbWT z(|HC%-m0rWjA$LEy*@BGwSZ*1x8i&>W@cx?@X^B_BGz#Op=V5dS5fG~Td`xS>lg<9 zWZMtS{rJX#VR1MZmzIW~BwQams**0}=BMIaV(eQFc>J&TfN9-`ssnK8ODnI-t42o$ zjP7P&7dYybA+6Ola4^`@qV4xyN^vW86daY{xxZeI5mBP*U#N?&FjlKF74^38bQ)e~ z{p8%YKp7)W$*GO}iu;Mk{Z8j$wd1*_xLI zR={KQ^nL~jEO~Zg86j7 zdA`d~pr^!CGVgXTO{6cRjPoFIbT!<5yC!{gbt_Z@?jSjheB_Q4GTP9wtYT25BgOEu z_p8&os>-L$C7XDi=_(yuv;=*W=D*HLc~g+l`RciMtZd1KCQpltdI`7DWbZz&&SXfn z?S5isJZ(InGdoH3Xp=L!@eeB$V#0%%fJvT%q5 zjeH!HrF1ry50)gSbfhV5lX6Rv-rum^QyCF|9Wi!usJ4=D|Ep@KRbkJBB2xOL zDA$g?uZP=OsPEtImL_jsc@45q#t#=fD_oAF)cJD95>gVoM(=lL)`8T}{}NkAEn4C?YP%+7I}|s6A(+2N+WJfF&Mi#67C%Lz z!uwpnmJdmYcxnQkwB)!{&|=1WdnIMbSNQP3t<|5P1=nmnd!kDYO9A*;euq5@oHcJFSbEs-RXb}xVLf58JuFvhvS+Wf4T3o@K7&@iCfPC+=|lKb!!gm zgs$rsSn-w{Hg`y(#bx1?Twy5GvCKL(&Bd|bzT2KJAC98Op(XH(niJGQ$LUvCw_7ah z!a}>p)UqpC242Gz$6N}s(A2VgE4<>Vflu%^H%RFPH4}`)t1JT_hGEJ0Y6>ozySlku z3&2qX4w|4SdDa0=SFhc)X|N+~QH(jXo|XIe2|;%f^s(?_J0BIPSN!mmPxdFwquT^d zel-V%_f)>OvrRRhkC61?8#)p^u{)ylqLVQzLpBAD*QD}|dd|Vc5H)Dm$ns@-@`mOL zu~#?Hy^;egTnsM4^$YyX%YlyUFK-gwoH!?o!%8D$L~IK+96np50%3k;Q-jB_6Skg5 zX4gp71rd1mwfiEwV>+|nAOg_4dNto)xex2!v|IAkkL_*m@}=DNR(aF#Mt9dU2Fg_- z(G1@+*E$0wo1-`O6^XXK*>6McERx@@^tGe-{!Q9TL_Vv}Yg?b+aZw_j6L`P6nK$Kz zTv<`~)Yn>^?I|z+OfPcrf(4`%IFE&_ggl|@(yxy9R8#ixayA#>KjXXajMDowo5qmwZ5U+KKB?(Sy zI$jOQ$L<(pS;#ajGsD4a5ZYqWoAEOwOVqxJfC0ZW z=K4POHE-HhYWzyLs*z3ME3I&w&yBaAVG}eGv56X_=;5%%?acifO8#avB6-7m_Sk&@ z@Q&zrlLv5+Kv(&0wpf(3ruQ66&GwH0>wy~ssZXNXfxWrG8Hi0kHF@s}M`{{io?fqc znF~;hPlVj01~6YN3P2)(MMYDY`J4+4lfTsP!~QO}J_ygTaJll;tb)&`Rj%=#*OfIL zd;>=#5aAW}-L~Nn`LnmCnh|rBJlfsr4tW z0}+4cwl(*?29wrSG&ztNJe8GHW!HjQH$aqtbveVc=UT12RggEvoyzq!0EfjJKtE~}sKg?-bQ_*ZD+|QxnR~7$}M<9GZ-oZBjG~_q<$cLxUbyC>=9z~je@3%7hUg#cl zr#YRsAmeD&$$${4w}ZzOf@&YhRqLnrRsOEGoIg7kw`8Zq9;+T%21z?Gzn~?EpnV1* z424<+!z6_d~ypT^G_7TQw);>{Sh?mQH5cTIjvPLYpu-xOk z5rG^b>&fvEo_RP6bquNnGER`3DYV-XL~B_B^!PHM_-FCPq< z8f~NnIx?K}@=3YiC@YK@6*WShdqk<0gb3vbat6LoHbti+$YHw!r<}0g;4TF}uaG#) z`}TSyRu!cdYN{b|^(h7tGOamI0PRXoNrh_47KG&(2p`RTnM|3-@eKAEEW%Z&rT&A@Xu8B!;XAe5k7QNE54x8{!eR6D!`n z!buaWy2GHuQ)$~`Pct0wUsC;ES4L#Q1|O=Sl4K2b$7oWA<}35OLc&c(KFalNZ8BIm z&trP9!Z6$8N948~U{i`JR?BCXPa~?HJ8ErW_g}Z6&ugXFLVO zx@bwVdMJVTlnjna62^y0kL(&Tu^L}2o8u8e054%xBT-;FirZ7O3{7zc3BSzQ@`w>q zf*Nw3kB?$&gMy?pc znPLw|z)>SBfo>}+MzyX>LM_}}lfyO)_acicW$>E;^D}3%N;Rx-rO{~Y_QxDSSL=ML zl*-Co7WeQ73CTV_5-S`O9eG3Hm(9gZ@?%#f<*=aN)dS-*Dklr=gEer=uE4G+vcqg4 z2tg2W3LdGvGJlw^sVK|8Z8_^fNz44dGKNX0gbRh2NmkiVHqO&SytBX(_h75h4b!Mmu~7IP~E?PJBq z6CC;4LG#iHOVI0X$hj=e!o!jCejN+0uTr>G`H#B1bV^|-P=kjAnOAjOXXL}HCI_Y3 zh`L$OEK`>Dt>F04iMa%G3Yy<4I4%X+Db=L_GFcen_)zfd2nSv){Q*+81spyC-nOe) z?A|MI)J_iAE%!;ZN$jWWdZW76#2{b6pj4fzrmsQZNW;3Ez*X<1jie=YSLl{dsX#*sCtj|G(q2~a;EUD7)GZ=q3p0hEehnG?%Fq=gOQ z5hizUP63IYxf(t7Ip#stzJeP6Q+6k!*@0>VzGR)u$dD*Fl(RKgBE?U1%61n>@O6Cf zkeZ&4QGBCWMG3F@jg6)vx5oHOdKZEH6>VRfGY4anguY)6Ao!qLt#b}1_UEYzYN zsyq_`mqn@ARV-f}`s1lqlkm$!dShb`;4<3Y%zYjk-Z~J^WGi%22p7q-OwJf}jA+qb zWxTT>RXpeuC!S#JdvNG5`ZwL6FxD_pvyAdpOLkU^b-rRHpFhj**H9d&s#KWKoMNC} z>khp}#gASB;`)&EEI-N37qxF-<07w?LrozuBi~Lyb%xkQE5MX0hSv)T26E}#vBI#N z8cs;X61+Ih2fF+Xiu}Ei-;WQ9G*E)2 z3cyjWs-bWBXbEx9V52$Z>v9rdcMa23H3CG2QZR1uhk&qGGxsJMwLhIdEys*3DLVPD zMl=UX9agCYNy%1$1wQ`pnPsn_NYQwL(C4t8FUC{nGy~6G^6>_I+pj8!*{fRf(P$33GundH-4^NjP#DI(z1ye*V8G@Ip-brInNDLT!ay7@%4y7|I-R~&0Jh$&58b_!6R&>a_IRO;R<48 z1?3il=bl~Wo2&b}d=b>dMi4_eCY<$xaug_Z`Zb-XH_ZM*3JYYS95k;+lwZ>F~;EjDzJO|63c}8 zSXt!#u~z9dLeewkCwN|_5d<_9N$itS1fbWjfNiUg*k#G^C{L`~sP>^Sclb~Im}7M+ z;h1Kfz`k8QmLjv1);{5q>}hd&q{E0wmjX)Kp3f$phyzeSMB_Vx_k&t=|JFG9OarLY z`KqOtn--tlKuI|+za%Mqk14*>dx4aYatb`;@#&d@CZe(7es5_FAXeDC%b3g<4; zMgW#|+R4fGBHCoI#JFhhTGG%~vt`250>`~r;b(+&XS`WjYyhg<0K-T(i4*$UbNj1U zBX1n4^abFTY3%eZIR;X~w_pBbyMhaSC(c&DnOz~}5j;?uurytrv$Yml>Y|GzAuocu zle{dnq_-_mMJ*vj0L4@+Ca(nT64ofxit+tW6x6X)VV8#BNV@~<*bF6zR;tHUDD&0> z(B53)599j~f?i|=RRcDh zxf7-4{*Ax43(kAvLj<7Hyl(BoSch#%7z4RkBmswks@w^AJu*$5y(8cSS5Q6ZaF&Si`3`#An0`~D@Da&o;bu8E&9hafV`V5}L4r!;n(rGF;c}DU6bi{ z4*uj2L*%nF>^t!f{+_A=wFnN>W+)VlK##U09G_R$K$jMks#7xhQV$SMt){^*5If(l z04bink4azuYX0XR^pZDOn>LLWm0HS<{&o(%t&TAmF1)`yX}jl3JiDGiJrNS0;X7qD z-j_de-CiIy*d9Gqe#ipXpsDDeGSX7%1NT!B498j%n(Fjp9mK2(r+p3!>?8oz^mfsI z+V6sV_(c%sNYl7OZ!1x_!WIfBV}ydHzZi@)E#o(U7Q<}5+j0vyYHk{ckb=p&=EwmM zIdn0!!Z`=V7gX1UL+y7E`HgRuy`s+zW(F_D`CKA{kjGLHOaO?F_xntTrGf_K4TE_= zIw@XC1-A;XRu~EPEY0htl&VIW#8P%?Dkl~h7qNf@k6lM>AQbruV=wM258F)W!C|JW z-%wcQ4m+$0H3C-V_~0Q8eZW_>IsK=!*H|S4Iciff`}hf>BQvqhl$1MU-9V2DUQx5d(3X*wa38i8v#GS2RwIm=`%D^u7OXl? z$^SIy+XI=u7T;4AO>=vFRuF(++5U6|zuxAvAeyio?ZaVC%u!JSYMA==&cM!y&cx2_ zPHgByC%*@Jgb(lBAGTms&JG7x3}3C}&Cdedk>Za+*>~;=XMAwxLikGBdQQ?(@k@TE ziE22FRM><blA% zjA&9JWSjX)<1oGaAoAaW)!O7LqYgakYa;(=@dar3o^=1SpaeAh z;L!eAq5@jJb6cy9ISIu{TCH^V)n5J=o(Gu6YE}EQG++qDlCO@)tX8o1Ly}2vo7Uz; z%Ue~>-+LX3zI=CfRi+TwM1l`}K%HH+I=nUFsev`uX)4}hS7gdHpiTxn8t2w3Xh0Dh z_&0i%5G)(i1!N(oeCxtJrfje=6ejCT%+38 zmVJiJ0f0)n;ZbcW5K2>E2e*s7zp>g~39-;8fV~*2yHQag6&Scwi)7zD*lJ39iC-&2 zu2ln*ev}*2D~Ip~Q3HCjsgPF5)b^Ia!LA-g$CbjdfC?**>lik_E3zMX{1^ryJ4#D? zA5;W?GGP+-txOIl#JVpGRxFBu})+MX5mYxl?g__+djPJlJsdqiGtHF> z#7)&oWvGy?qU%^H$-&ej<1fx>Qb^6u!18q7(kV--9H-N034|mia}T;{gC}|eN_HSb z?-N|fdqH>Xj(6oE4dQogZ2V-G{UrbEq(>TW&&z9n71187DNQN*^6H6-<&L15U1RG- zVl<}mvWST_)x?vHkz3WZF;GXEh&+>};u%a;_KO>T2{>u{wQ{K1aSg@9GcAGd(T9La z?LF|eo0tEpscx$x7K$A!Q99dvmQ?0J8kM`VQDnc@>M{{8(Go3oqP8VUI+=#y(M(}` znLM>j)V>GvXNuk7SWg z{S*ESv*~JTP5kL7k2f08EgDZh*I;teh9l!?<M6SCYL#)m{T3cs8wZy$%{;>_4@n^8-qhS@bZ>Z_eJqaMe%T{v=!psts;z#R@K z33Q94r*keXnbx0RYPSzGVvVyr^H;RnMq~3$(3o_%3e;okG4&z;@Q*MON+p4yyQEt;(@!?5R85b_K+UuEgpREro@%gNx^(~m5 z5eW%C%Dff8QS4}D_GRYLT2gnh91CBy{yH{jsAIX=o&!{%MXyZjsU0I^Nf=?IT3x!J z^%e0@UW^U)LH2vE*-Nl5UCPtSZlxA2D&D@suBlRd?q)i0 zDXVMHwZS8qcMR)Nv27;Ldcrb<0HSwX|W&BLvoi0X-qYA5PcZ^fO}KUkVj0eiK5Y$>t-)bcJL5vcM9CAn!`@V z$3~y_G#CmcO~YP38Lrx}!{{GA#98WP4k;_r-sFwGwjOSGW0DaRpdLB|0A5wy_M+&7pc}7_86?oC7NL%s^ z{Xu5n!LlN>q>t8G!o7Oh=kjL+((Cfx>MaSQYDnOK*;9jR=*feUGIH*X%AONkscUWP z6RUGSEBAdneF2bOgyaSsd)Tif{9TP~ z3nt~J(;C`2>_59PURKg1b6o;z^3kc$)OQ9FY{=zCr3aO6Xdb!!^^?PGYHY3;0(V`* zD>rr5s@o9IVE=p~SMtmKliO zdzC@Gz7_GiUG#c(Cd2~0!>$gCx?Ss1L-4rm8AVwlDrYy zeY<*?#fy+SeB=dklZKpk&Fwd?F7F?I`1oH3oW29InL}5jnwHmz(9UsZYMR5W{X=to zrG6Pb`ytu5vgFsB3Jc_nv%c^2bL{@O6EhY5eAXITgQHc7Zh;u2H9V@>xK{yGWN=Lf ziyRxh?3=cSpJWfp_SxSUT?p8$&zq|OMY zrVE19nyXP!v@&)~yE&vBBHOMn#bG-pHf6M@6{|0q4^ne-R*ma870Zq?AWxhdmY%?m z_B;$~+lM0Gtkx{9DoS;ITagsa%kV1CNY9)#!+0@I_=~sOVxFjR0{TijwGGolI`7E% z5B3Sn@qvtM!WS*9UI0*7jt(xlS1vjh*kE5jx8=tz?g3>vV14PZ5*)77E19a_cq+hd zu0T6m#d&{Mr21mD>wv!V;Jdi;%F3YBr52$N*6TQ&!C^aHG0;>dq&Jln$PTgYMv6%+iZbRkK5?HYUk?OZtZ-gx_n>|I994^{0o<(}Z@p$%cO2NIXO>c5a9g;6#)n(Sp4;YhsC(&} zbxak|dgd3B-^O1uICO1O8U*Q}@ro^bG1Vg`-=t^B>pk^(_F`9K+2XaK4OqN|?3iy) zU>u$exIV&g_xvS&t3m6EfX(}3){?^2Tus6s;~;&tQRQq_@MAfV_Xe57S+wb&hE1FI zKW|yz{Ao((%brJ}_q2wIKD+REo1 z(@#-vZ$RIqg)gmt@A$vFl=thU*ln8fRT#?=2M4)zOw~+QL(`J$m1XRHSLp zQmt{*qL$~1h*&@S-xu`m9+&RU4ti^Jk>J-}JIUNlIM}giquuai#*S0omrVsKB9zW` zBKtG`_mNf;I`q$MP()C-t|rRERCD>>HAf}@jC|e7&E6wfQw$99~$uT0!VT_w(!3C>$Ozx zzi-0TiS^n2z;E{(8a8s)a>g_p0yv7_b;{H1NFF)!+q71AhJk~YbYKt9>odtpS`~b> z!_{(Q#9Cg}XP7GyJHJ7sH*%pL5x=$Q+uD)pn|?p@Ov!Gqv#CS*N;7f^;HV-_@+ksv zNcB%Q`dU_7E%wOM@~CW{1B1D@$3U&%QlYkoDqL)pJ{UCn>4vR!O@yK4&B8y%bKBNk zcZ_evuA3Qhv-kAD{3_h}wYj7{zT}lg4aoc(uQ#zgqV¥GM)Uj*JI~2>W5_H`UyH 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 QxIA`aL(?;P2KM*=57?TUz5oCK literal 54602 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 WEcM#6>#v0vo0?b}mz=x)>;D1wJ{2wi diff --git a/migrations/0003_curved_mariko_yashida.sql b/migrations/0003_curved_mariko_yashida.sql new file mode 100644 index 0000000..f640a59 --- /dev/null +++ b/migrations/0003_curved_mariko_yashida.sql @@ -0,0 +1,90 @@ +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 DEFAULT now() NOT NULL, + "updated_at" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE "apikey" ( + "id" text PRIMARY KEY NOT NULL, + "name" text, + "start" text, + "prefix" text, + "key" text NOT NULL, + "user_id" text NOT NULL, + "refill_interval" integer, + "refill_amount" integer, + "last_refill_at" timestamp, + "enabled" boolean DEFAULT true, + "rate_limit_enabled" boolean DEFAULT true, + "rate_limit_time_window" integer DEFAULT 86400000, + "rate_limit_max" integer DEFAULT 10, + "request_count" integer DEFAULT 0, + "remaining" integer, + "last_request" timestamp, + "expires_at" timestamp, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "permissions" text, + "metadata" text +); +--> statement-breakpoint +CREATE TABLE "jwks" ( + "id" text PRIMARY KEY NOT NULL, + "public_key" text NOT NULL, + "private_key" text NOT NULL, + "created_at" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE "session" ( + "id" text PRIMARY KEY NOT NULL, + "expires_at" timestamp NOT NULL, + "token" text NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp NOT NULL, + "ip_address" text, + "user_agent" text, + "user_id" text NOT NULL, + "impersonated_by" text, + CONSTRAINT "session_token_unique" UNIQUE("token") +); +--> statement-breakpoint +CREATE TABLE "user" ( + "id" text PRIMARY KEY NOT NULL, + "name" text NOT NULL, + "email" text NOT NULL, + "email_verified" boolean DEFAULT false NOT NULL, + "image" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "role" text, + "banned" boolean DEFAULT false, + "ban_reason" text, + "ban_expires" timestamp, + "username" text, + "display_username" text, + CONSTRAINT "user_email_unique" UNIQUE("email"), + CONSTRAINT "user_username_unique" UNIQUE("username") +); +--> statement-breakpoint +CREATE TABLE "verification" ( + "id" text PRIMARY KEY NOT NULL, + "identifier" text NOT NULL, + "value" text NOT NULL, + "expires_at" timestamp NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> 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 "apikey" ADD CONSTRAINT "apikey_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade 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; \ No newline at end of file diff --git a/migrations/0004_panoramic_longshot.sql b/migrations/0004_panoramic_longshot.sql new file mode 100644 index 0000000..7fa7e9a --- /dev/null +++ b/migrations/0004_panoramic_longshot.sql @@ -0,0 +1 @@ +ALTER TABLE "user" ADD COLUMN "last_login" timestamp; \ No newline at end of file diff --git a/migrations/0005_gorgeous_purple_man.sql b/migrations/0005_gorgeous_purple_man.sql new file mode 100644 index 0000000..65c0302 --- /dev/null +++ b/migrations/0005_gorgeous_purple_man.sql @@ -0,0 +1,9 @@ +CREATE TABLE "user_role" ( + "user_role_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" text NOT NULL, + "module" text NOT NULL, + "role" text NOT NULL +); +--> statement-breakpoint +ALTER TABLE "user_role" ADD CONSTRAINT "user_role_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "unique_user_module" ON "user_role" USING btree ("user_id","module"); \ No newline at end of file diff --git a/migrations/meta/0003_snapshot.json b/migrations/meta/0003_snapshot.json new file mode 100644 index 0000000..19a06af --- /dev/null +++ b/migrations/meta/0003_snapshot.json @@ -0,0 +1,744 @@ +{ + "id": "0e050a96-8de7-4634-9f8e-0f3ba69c187a", + "prevId": "922093ba-6949-4d30-9c17-007257754cf2", + "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", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "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": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "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", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "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", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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 + } + }, + "indexes": {}, + "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": 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, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "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", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "log_id": { + "name": "log_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "level": { + "name": "level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subModule": { + "name": "subModule", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stack": { + "name": "stack", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "checked": { + "name": "checked", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "settings_id": { + "name": "settings_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moduleName": { + "name": "moduleName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[\"systemAdmin\"]'::jsonb" + }, + "add_User": { + "name": "add_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "add_Date": { + "name": "add_Date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_User": { + "name": "upd_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "name": { + "name": "name", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0004_snapshot.json b/migrations/meta/0004_snapshot.json new file mode 100644 index 0000000..0fa0329 --- /dev/null +++ b/migrations/meta/0004_snapshot.json @@ -0,0 +1,750 @@ +{ + "id": "ec376ba2-db90-487c-b82a-d033a2c60244", + "prevId": "0e050a96-8de7-4634-9f8e-0f3ba69c187a", + "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", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "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": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "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", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "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", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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 + } + }, + "indexes": {}, + "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": 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, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "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", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "log_id": { + "name": "log_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "level": { + "name": "level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subModule": { + "name": "subModule", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stack": { + "name": "stack", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "checked": { + "name": "checked", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "settings_id": { + "name": "settings_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moduleName": { + "name": "moduleName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[\"systemAdmin\"]'::jsonb" + }, + "add_User": { + "name": "add_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "add_Date": { + "name": "add_Date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_User": { + "name": "upd_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "name": { + "name": "name", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0005_snapshot.json b/migrations/meta/0005_snapshot.json new file mode 100644 index 0000000..53bda96 --- /dev/null +++ b/migrations/meta/0005_snapshot.json @@ -0,0 +1,824 @@ +{ + "id": "639e50c0-757a-4867-a78e-48e8e1a416fc", + "prevId": "ec376ba2-db90-487c-b82a-d033a2c60244", + "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", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "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": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "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", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "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", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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 + } + }, + "indexes": {}, + "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": 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, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "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", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "log_id": { + "name": "log_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "level": { + "name": "level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subModule": { + "name": "subModule", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stack": { + "name": "stack", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "checked": { + "name": "checked", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "settings_id": { + "name": "settings_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moduleName": { + "name": "moduleName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[\"systemAdmin\"]'::jsonb" + }, + "add_User": { + "name": "add_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "add_Date": { + "name": "add_Date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_User": { + "name": "upd_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "name": { + "name": "name", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_role": { + "name": "user_role", + "schema": "", + "columns": { + "user_role_id": { + "name": "user_role_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "unique_user_module": { + "name": "unique_user_module", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "module", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_role_user_id_user_id_fk": { + "name": "user_role_user_id_user_id_fk", + "tableFrom": "user_role", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json index 1509705..a1d57c5 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -22,6 +22,27 @@ "when": 1756843987534, "tag": "0002_mean_nuke", "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1758076031154, + "tag": "0003_curved_mariko_yashida", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1758079206432, + "tag": "0004_panoramic_longshot", + "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1758081790572, + "tag": "0005_gorgeous_purple_man", + "breakpoints": true } ] } \ No newline at end of file