@ravxd/velocitydb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1 @@
1
+ DATABASE_URL=postgresql://user:password@host:5432/dbname
package/bun.lock ADDED
@@ -0,0 +1,211 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "@velocity/db",
6
+ "dependencies": {
7
+ "date-fns": "^4.2.1",
8
+ },
9
+ "devDependencies": {
10
+ "@types/node": "^25.9.1",
11
+ "drizzle-kit": "^0.31.0",
12
+ "drizzle-orm": "^0.45.2",
13
+ "postgres": "^3.4.0",
14
+ "typescript": "^5.8.0",
15
+ },
16
+ "peerDependencies": {
17
+ "drizzle-orm": "^0.45.2",
18
+ "postgres": "^3.4.0",
19
+ },
20
+ },
21
+ },
22
+ "packages": {
23
+ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
24
+
25
+ "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
26
+
27
+ "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="],
28
+
29
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
30
+
31
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
32
+
33
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
34
+
35
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
36
+
37
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
38
+
39
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
40
+
41
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
42
+
43
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
44
+
45
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
46
+
47
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
48
+
49
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
50
+
51
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
52
+
53
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
54
+
55
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
56
+
57
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
58
+
59
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
60
+
61
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
62
+
63
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
64
+
65
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
66
+
67
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
68
+
69
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
70
+
71
+ "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
72
+
73
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
74
+
75
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
76
+
77
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
78
+
79
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
80
+
81
+ "@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="],
82
+
83
+ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
84
+
85
+ "date-fns": ["date-fns@4.2.1", "", {}, "sha512-37RhSdxaG1suen6VDCza6rNrQfooyQh57HFVPwQGEq2QWliVLzPQZ8Oa017weOu+HZCnzI7N3Pf/wyoBKfEqrA=="],
86
+
87
+ "drizzle-kit": ["drizzle-kit@0.31.10", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "tsx": "^4.21.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw=="],
88
+
89
+ "drizzle-orm": ["drizzle-orm@0.45.2", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q=="],
90
+
91
+ "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
92
+
93
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
94
+
95
+ "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="],
96
+
97
+ "postgres": ["postgres@3.4.9", "", {}, "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw=="],
98
+
99
+ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
100
+
101
+ "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
102
+
103
+ "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
104
+
105
+ "tsx": ["tsx@4.22.3", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg=="],
106
+
107
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
108
+
109
+ "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
110
+
111
+ "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
112
+
113
+ "tsx/esbuild": ["esbuild@0.28.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.0", "@esbuild/android-arm": "0.28.0", "@esbuild/android-arm64": "0.28.0", "@esbuild/android-x64": "0.28.0", "@esbuild/darwin-arm64": "0.28.0", "@esbuild/darwin-x64": "0.28.0", "@esbuild/freebsd-arm64": "0.28.0", "@esbuild/freebsd-x64": "0.28.0", "@esbuild/linux-arm": "0.28.0", "@esbuild/linux-arm64": "0.28.0", "@esbuild/linux-ia32": "0.28.0", "@esbuild/linux-loong64": "0.28.0", "@esbuild/linux-mips64el": "0.28.0", "@esbuild/linux-ppc64": "0.28.0", "@esbuild/linux-riscv64": "0.28.0", "@esbuild/linux-s390x": "0.28.0", "@esbuild/linux-x64": "0.28.0", "@esbuild/netbsd-arm64": "0.28.0", "@esbuild/netbsd-x64": "0.28.0", "@esbuild/openbsd-arm64": "0.28.0", "@esbuild/openbsd-x64": "0.28.0", "@esbuild/openharmony-arm64": "0.28.0", "@esbuild/sunos-x64": "0.28.0", "@esbuild/win32-arm64": "0.28.0", "@esbuild/win32-ia32": "0.28.0", "@esbuild/win32-x64": "0.28.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw=="],
114
+
115
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="],
116
+
117
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="],
118
+
119
+ "@esbuild-kit/core-utils/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.18.20", "", { "os": "android", "cpu": "x64" }, "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg=="],
120
+
121
+ "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.18.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA=="],
122
+
123
+ "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.18.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ=="],
124
+
125
+ "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.18.20", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw=="],
126
+
127
+ "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.18.20", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ=="],
128
+
129
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.18.20", "", { "os": "linux", "cpu": "arm" }, "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg=="],
130
+
131
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.18.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA=="],
132
+
133
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.18.20", "", { "os": "linux", "cpu": "ia32" }, "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA=="],
134
+
135
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg=="],
136
+
137
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ=="],
138
+
139
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.18.20", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA=="],
140
+
141
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A=="],
142
+
143
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.18.20", "", { "os": "linux", "cpu": "s390x" }, "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ=="],
144
+
145
+ "@esbuild-kit/core-utils/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.18.20", "", { "os": "linux", "cpu": "x64" }, "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w=="],
146
+
147
+ "@esbuild-kit/core-utils/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.18.20", "", { "os": "none", "cpu": "x64" }, "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A=="],
148
+
149
+ "@esbuild-kit/core-utils/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.18.20", "", { "os": "openbsd", "cpu": "x64" }, "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg=="],
150
+
151
+ "@esbuild-kit/core-utils/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.18.20", "", { "os": "sunos", "cpu": "x64" }, "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ=="],
152
+
153
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.18.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg=="],
154
+
155
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.18.20", "", { "os": "win32", "cpu": "ia32" }, "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g=="],
156
+
157
+ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="],
158
+
159
+ "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA=="],
160
+
161
+ "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.28.0", "", { "os": "android", "cpu": "arm" }, "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ=="],
162
+
163
+ "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.0", "", { "os": "android", "cpu": "arm64" }, "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw=="],
164
+
165
+ "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.28.0", "", { "os": "android", "cpu": "x64" }, "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA=="],
166
+
167
+ "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q=="],
168
+
169
+ "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ=="],
170
+
171
+ "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q=="],
172
+
173
+ "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw=="],
174
+
175
+ "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw=="],
176
+
177
+ "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A=="],
178
+
179
+ "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ=="],
180
+
181
+ "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg=="],
182
+
183
+ "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w=="],
184
+
185
+ "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg=="],
186
+
187
+ "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ=="],
188
+
189
+ "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q=="],
190
+
191
+ "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.0", "", { "os": "linux", "cpu": "x64" }, "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ=="],
192
+
193
+ "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw=="],
194
+
195
+ "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.0", "", { "os": "none", "cpu": "x64" }, "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw=="],
196
+
197
+ "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g=="],
198
+
199
+ "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA=="],
200
+
201
+ "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w=="],
202
+
203
+ "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw=="],
204
+
205
+ "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA=="],
206
+
207
+ "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA=="],
208
+
209
+ "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.0", "", { "os": "win32", "cpu": "x64" }, "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw=="],
210
+ }
211
+ }
@@ -0,0 +1,74 @@
1
+ CREATE TYPE "public"."link_status" AS ENUM('unlinked', 'linked', 'pending');--> statement-breakpoint
2
+ CREATE TYPE "public"."member_role" AS ENUM('member', 'officer', 'guildmaster');--> statement-breakpoint
3
+ CREATE TYPE "public"."request_status" AS ENUM('pending', 'approved', 'rejected');--> statement-breakpoint
4
+ CREATE TABLE "afk_entries" (
5
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
6
+ "member_id" uuid NOT NULL,
7
+ "afk_date" date NOT NULL,
8
+ "notes" text,
9
+ "created_at" timestamp DEFAULT now() NOT NULL
10
+ );
11
+ --> statement-breakpoint
12
+ CREATE TABLE "characters" (
13
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
14
+ "member_id" uuid NOT NULL,
15
+ "name" text NOT NULL,
16
+ "realm" text NOT NULL,
17
+ "class" text NOT NULL,
18
+ "spec" text NOT NULL,
19
+ "status" text DEFAULT 'active' NOT NULL,
20
+ "is_main" boolean DEFAULT false NOT NULL,
21
+ "wowutils_character_id" text,
22
+ "created_at" timestamp DEFAULT now() NOT NULL,
23
+ "updated_at" timestamp DEFAULT now() NOT NULL,
24
+ CONSTRAINT "characters_wowutils_character_id_unique" UNIQUE("wowutils_character_id")
25
+ );
26
+ --> statement-breakpoint
27
+ CREATE TABLE "members" (
28
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
29
+ "discord_id" text NOT NULL,
30
+ "discord_username" text NOT NULL,
31
+ "display_name" text NOT NULL,
32
+ "battletag" text,
33
+ "role" "member_role" DEFAULT 'member' NOT NULL,
34
+ "is_admin" boolean DEFAULT false NOT NULL,
35
+ "wowutils_member_id" text,
36
+ "wowutils_alias" text,
37
+ "wowutils_rank" text,
38
+ "wowutils_main_role" text,
39
+ "link_status" "link_status" DEFAULT 'unlinked' NOT NULL,
40
+ "created_at" timestamp DEFAULT now() NOT NULL,
41
+ "updated_at" timestamp DEFAULT now() NOT NULL,
42
+ CONSTRAINT "members_discord_id_unique" UNIQUE("discord_id"),
43
+ CONSTRAINT "members_wowutils_member_id_unique" UNIQUE("wowutils_member_id")
44
+ );
45
+ --> statement-breakpoint
46
+ CREATE TABLE "requests" (
47
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
48
+ "member_id" uuid NOT NULL,
49
+ "character_id" uuid,
50
+ "character_name" text NOT NULL,
51
+ "class_spec" text NOT NULL,
52
+ "notes" text,
53
+ "week_start" date NOT NULL,
54
+ "status" "request_status" DEFAULT 'pending' NOT NULL,
55
+ "created_at" timestamp DEFAULT now() NOT NULL,
56
+ "updated_at" timestamp DEFAULT now() NOT NULL
57
+ );
58
+ --> statement-breakpoint
59
+ CREATE TABLE "sync_state" (
60
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
61
+ "last_synced_at" timestamp DEFAULT now() NOT NULL,
62
+ "synced_by" text
63
+ );
64
+ --> statement-breakpoint
65
+ ALTER TABLE "afk_entries" ADD CONSTRAINT "afk_entries_member_id_members_id_fk" FOREIGN KEY ("member_id") REFERENCES "public"."members"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
66
+ ALTER TABLE "characters" ADD CONSTRAINT "characters_member_id_members_id_fk" FOREIGN KEY ("member_id") REFERENCES "public"."members"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
67
+ ALTER TABLE "requests" ADD CONSTRAINT "requests_member_id_members_id_fk" FOREIGN KEY ("member_id") REFERENCES "public"."members"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
68
+ ALTER TABLE "requests" ADD CONSTRAINT "requests_character_id_characters_id_fk" FOREIGN KEY ("character_id") REFERENCES "public"."characters"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
69
+ CREATE INDEX "afk_entries_member_id_idx" ON "afk_entries" USING btree ("member_id");--> statement-breakpoint
70
+ CREATE INDEX "afk_entries_date_idx" ON "afk_entries" USING btree ("afk_date");--> statement-breakpoint
71
+ CREATE INDEX "characters_member_id_idx" ON "characters" USING btree ("member_id");--> statement-breakpoint
72
+ CREATE INDEX "members_discord_id_idx" ON "members" USING btree ("discord_id");--> statement-breakpoint
73
+ CREATE INDEX "requests_week_start_idx" ON "requests" USING btree ("week_start");--> statement-breakpoint
74
+ CREATE INDEX "requests_member_id_idx" ON "requests" USING btree ("member_id");
@@ -0,0 +1,564 @@
1
+ {
2
+ "id": "9a025d09-a4e2-4cfe-ba2c-deaf88eef84c",
3
+ "prevId": "00000000-0000-0000-0000-000000000000",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.afk_entries": {
8
+ "name": "afk_entries",
9
+ "schema": "",
10
+ "columns": {
11
+ "id": {
12
+ "name": "id",
13
+ "type": "uuid",
14
+ "primaryKey": true,
15
+ "notNull": true,
16
+ "default": "gen_random_uuid()"
17
+ },
18
+ "member_id": {
19
+ "name": "member_id",
20
+ "type": "uuid",
21
+ "primaryKey": false,
22
+ "notNull": true
23
+ },
24
+ "afk_date": {
25
+ "name": "afk_date",
26
+ "type": "date",
27
+ "primaryKey": false,
28
+ "notNull": true
29
+ },
30
+ "notes": {
31
+ "name": "notes",
32
+ "type": "text",
33
+ "primaryKey": false,
34
+ "notNull": false
35
+ },
36
+ "created_at": {
37
+ "name": "created_at",
38
+ "type": "timestamp",
39
+ "primaryKey": false,
40
+ "notNull": true,
41
+ "default": "now()"
42
+ }
43
+ },
44
+ "indexes": {
45
+ "afk_entries_member_id_idx": {
46
+ "name": "afk_entries_member_id_idx",
47
+ "columns": [
48
+ {
49
+ "expression": "member_id",
50
+ "isExpression": false,
51
+ "asc": true,
52
+ "nulls": "last"
53
+ }
54
+ ],
55
+ "isUnique": false,
56
+ "concurrently": false,
57
+ "method": "btree",
58
+ "with": {}
59
+ },
60
+ "afk_entries_date_idx": {
61
+ "name": "afk_entries_date_idx",
62
+ "columns": [
63
+ {
64
+ "expression": "afk_date",
65
+ "isExpression": false,
66
+ "asc": true,
67
+ "nulls": "last"
68
+ }
69
+ ],
70
+ "isUnique": false,
71
+ "concurrently": false,
72
+ "method": "btree",
73
+ "with": {}
74
+ }
75
+ },
76
+ "foreignKeys": {
77
+ "afk_entries_member_id_members_id_fk": {
78
+ "name": "afk_entries_member_id_members_id_fk",
79
+ "tableFrom": "afk_entries",
80
+ "tableTo": "members",
81
+ "columnsFrom": [
82
+ "member_id"
83
+ ],
84
+ "columnsTo": [
85
+ "id"
86
+ ],
87
+ "onDelete": "cascade",
88
+ "onUpdate": "no action"
89
+ }
90
+ },
91
+ "compositePrimaryKeys": {},
92
+ "uniqueConstraints": {},
93
+ "policies": {},
94
+ "checkConstraints": {},
95
+ "isRLSEnabled": false
96
+ },
97
+ "public.characters": {
98
+ "name": "characters",
99
+ "schema": "",
100
+ "columns": {
101
+ "id": {
102
+ "name": "id",
103
+ "type": "uuid",
104
+ "primaryKey": true,
105
+ "notNull": true,
106
+ "default": "gen_random_uuid()"
107
+ },
108
+ "member_id": {
109
+ "name": "member_id",
110
+ "type": "uuid",
111
+ "primaryKey": false,
112
+ "notNull": true
113
+ },
114
+ "name": {
115
+ "name": "name",
116
+ "type": "text",
117
+ "primaryKey": false,
118
+ "notNull": true
119
+ },
120
+ "realm": {
121
+ "name": "realm",
122
+ "type": "text",
123
+ "primaryKey": false,
124
+ "notNull": true
125
+ },
126
+ "class": {
127
+ "name": "class",
128
+ "type": "text",
129
+ "primaryKey": false,
130
+ "notNull": true
131
+ },
132
+ "spec": {
133
+ "name": "spec",
134
+ "type": "text",
135
+ "primaryKey": false,
136
+ "notNull": true
137
+ },
138
+ "status": {
139
+ "name": "status",
140
+ "type": "text",
141
+ "primaryKey": false,
142
+ "notNull": true,
143
+ "default": "'active'"
144
+ },
145
+ "is_main": {
146
+ "name": "is_main",
147
+ "type": "boolean",
148
+ "primaryKey": false,
149
+ "notNull": true,
150
+ "default": false
151
+ },
152
+ "wowutils_character_id": {
153
+ "name": "wowutils_character_id",
154
+ "type": "text",
155
+ "primaryKey": false,
156
+ "notNull": false
157
+ },
158
+ "created_at": {
159
+ "name": "created_at",
160
+ "type": "timestamp",
161
+ "primaryKey": false,
162
+ "notNull": true,
163
+ "default": "now()"
164
+ },
165
+ "updated_at": {
166
+ "name": "updated_at",
167
+ "type": "timestamp",
168
+ "primaryKey": false,
169
+ "notNull": true,
170
+ "default": "now()"
171
+ }
172
+ },
173
+ "indexes": {
174
+ "characters_member_id_idx": {
175
+ "name": "characters_member_id_idx",
176
+ "columns": [
177
+ {
178
+ "expression": "member_id",
179
+ "isExpression": false,
180
+ "asc": true,
181
+ "nulls": "last"
182
+ }
183
+ ],
184
+ "isUnique": false,
185
+ "concurrently": false,
186
+ "method": "btree",
187
+ "with": {}
188
+ }
189
+ },
190
+ "foreignKeys": {
191
+ "characters_member_id_members_id_fk": {
192
+ "name": "characters_member_id_members_id_fk",
193
+ "tableFrom": "characters",
194
+ "tableTo": "members",
195
+ "columnsFrom": [
196
+ "member_id"
197
+ ],
198
+ "columnsTo": [
199
+ "id"
200
+ ],
201
+ "onDelete": "cascade",
202
+ "onUpdate": "no action"
203
+ }
204
+ },
205
+ "compositePrimaryKeys": {},
206
+ "uniqueConstraints": {
207
+ "characters_wowutils_character_id_unique": {
208
+ "name": "characters_wowutils_character_id_unique",
209
+ "nullsNotDistinct": false,
210
+ "columns": [
211
+ "wowutils_character_id"
212
+ ]
213
+ }
214
+ },
215
+ "policies": {},
216
+ "checkConstraints": {},
217
+ "isRLSEnabled": false
218
+ },
219
+ "public.members": {
220
+ "name": "members",
221
+ "schema": "",
222
+ "columns": {
223
+ "id": {
224
+ "name": "id",
225
+ "type": "uuid",
226
+ "primaryKey": true,
227
+ "notNull": true,
228
+ "default": "gen_random_uuid()"
229
+ },
230
+ "discord_id": {
231
+ "name": "discord_id",
232
+ "type": "text",
233
+ "primaryKey": false,
234
+ "notNull": true
235
+ },
236
+ "discord_username": {
237
+ "name": "discord_username",
238
+ "type": "text",
239
+ "primaryKey": false,
240
+ "notNull": true
241
+ },
242
+ "display_name": {
243
+ "name": "display_name",
244
+ "type": "text",
245
+ "primaryKey": false,
246
+ "notNull": true
247
+ },
248
+ "battletag": {
249
+ "name": "battletag",
250
+ "type": "text",
251
+ "primaryKey": false,
252
+ "notNull": false
253
+ },
254
+ "role": {
255
+ "name": "role",
256
+ "type": "member_role",
257
+ "typeSchema": "public",
258
+ "primaryKey": false,
259
+ "notNull": true,
260
+ "default": "'member'"
261
+ },
262
+ "is_admin": {
263
+ "name": "is_admin",
264
+ "type": "boolean",
265
+ "primaryKey": false,
266
+ "notNull": true,
267
+ "default": false
268
+ },
269
+ "wowutils_member_id": {
270
+ "name": "wowutils_member_id",
271
+ "type": "text",
272
+ "primaryKey": false,
273
+ "notNull": false
274
+ },
275
+ "wowutils_alias": {
276
+ "name": "wowutils_alias",
277
+ "type": "text",
278
+ "primaryKey": false,
279
+ "notNull": false
280
+ },
281
+ "wowutils_rank": {
282
+ "name": "wowutils_rank",
283
+ "type": "text",
284
+ "primaryKey": false,
285
+ "notNull": false
286
+ },
287
+ "wowutils_main_role": {
288
+ "name": "wowutils_main_role",
289
+ "type": "text",
290
+ "primaryKey": false,
291
+ "notNull": false
292
+ },
293
+ "link_status": {
294
+ "name": "link_status",
295
+ "type": "link_status",
296
+ "typeSchema": "public",
297
+ "primaryKey": false,
298
+ "notNull": true,
299
+ "default": "'unlinked'"
300
+ },
301
+ "created_at": {
302
+ "name": "created_at",
303
+ "type": "timestamp",
304
+ "primaryKey": false,
305
+ "notNull": true,
306
+ "default": "now()"
307
+ },
308
+ "updated_at": {
309
+ "name": "updated_at",
310
+ "type": "timestamp",
311
+ "primaryKey": false,
312
+ "notNull": true,
313
+ "default": "now()"
314
+ }
315
+ },
316
+ "indexes": {
317
+ "members_discord_id_idx": {
318
+ "name": "members_discord_id_idx",
319
+ "columns": [
320
+ {
321
+ "expression": "discord_id",
322
+ "isExpression": false,
323
+ "asc": true,
324
+ "nulls": "last"
325
+ }
326
+ ],
327
+ "isUnique": false,
328
+ "concurrently": false,
329
+ "method": "btree",
330
+ "with": {}
331
+ }
332
+ },
333
+ "foreignKeys": {},
334
+ "compositePrimaryKeys": {},
335
+ "uniqueConstraints": {
336
+ "members_discord_id_unique": {
337
+ "name": "members_discord_id_unique",
338
+ "nullsNotDistinct": false,
339
+ "columns": [
340
+ "discord_id"
341
+ ]
342
+ },
343
+ "members_wowutils_member_id_unique": {
344
+ "name": "members_wowutils_member_id_unique",
345
+ "nullsNotDistinct": false,
346
+ "columns": [
347
+ "wowutils_member_id"
348
+ ]
349
+ }
350
+ },
351
+ "policies": {},
352
+ "checkConstraints": {},
353
+ "isRLSEnabled": false
354
+ },
355
+ "public.requests": {
356
+ "name": "requests",
357
+ "schema": "",
358
+ "columns": {
359
+ "id": {
360
+ "name": "id",
361
+ "type": "uuid",
362
+ "primaryKey": true,
363
+ "notNull": true,
364
+ "default": "gen_random_uuid()"
365
+ },
366
+ "member_id": {
367
+ "name": "member_id",
368
+ "type": "uuid",
369
+ "primaryKey": false,
370
+ "notNull": true
371
+ },
372
+ "character_id": {
373
+ "name": "character_id",
374
+ "type": "uuid",
375
+ "primaryKey": false,
376
+ "notNull": false
377
+ },
378
+ "character_name": {
379
+ "name": "character_name",
380
+ "type": "text",
381
+ "primaryKey": false,
382
+ "notNull": true
383
+ },
384
+ "class_spec": {
385
+ "name": "class_spec",
386
+ "type": "text",
387
+ "primaryKey": false,
388
+ "notNull": true
389
+ },
390
+ "notes": {
391
+ "name": "notes",
392
+ "type": "text",
393
+ "primaryKey": false,
394
+ "notNull": false
395
+ },
396
+ "week_start": {
397
+ "name": "week_start",
398
+ "type": "date",
399
+ "primaryKey": false,
400
+ "notNull": true
401
+ },
402
+ "status": {
403
+ "name": "status",
404
+ "type": "request_status",
405
+ "typeSchema": "public",
406
+ "primaryKey": false,
407
+ "notNull": true,
408
+ "default": "'pending'"
409
+ },
410
+ "created_at": {
411
+ "name": "created_at",
412
+ "type": "timestamp",
413
+ "primaryKey": false,
414
+ "notNull": true,
415
+ "default": "now()"
416
+ },
417
+ "updated_at": {
418
+ "name": "updated_at",
419
+ "type": "timestamp",
420
+ "primaryKey": false,
421
+ "notNull": true,
422
+ "default": "now()"
423
+ }
424
+ },
425
+ "indexes": {
426
+ "requests_week_start_idx": {
427
+ "name": "requests_week_start_idx",
428
+ "columns": [
429
+ {
430
+ "expression": "week_start",
431
+ "isExpression": false,
432
+ "asc": true,
433
+ "nulls": "last"
434
+ }
435
+ ],
436
+ "isUnique": false,
437
+ "concurrently": false,
438
+ "method": "btree",
439
+ "with": {}
440
+ },
441
+ "requests_member_id_idx": {
442
+ "name": "requests_member_id_idx",
443
+ "columns": [
444
+ {
445
+ "expression": "member_id",
446
+ "isExpression": false,
447
+ "asc": true,
448
+ "nulls": "last"
449
+ }
450
+ ],
451
+ "isUnique": false,
452
+ "concurrently": false,
453
+ "method": "btree",
454
+ "with": {}
455
+ }
456
+ },
457
+ "foreignKeys": {
458
+ "requests_member_id_members_id_fk": {
459
+ "name": "requests_member_id_members_id_fk",
460
+ "tableFrom": "requests",
461
+ "tableTo": "members",
462
+ "columnsFrom": [
463
+ "member_id"
464
+ ],
465
+ "columnsTo": [
466
+ "id"
467
+ ],
468
+ "onDelete": "cascade",
469
+ "onUpdate": "no action"
470
+ },
471
+ "requests_character_id_characters_id_fk": {
472
+ "name": "requests_character_id_characters_id_fk",
473
+ "tableFrom": "requests",
474
+ "tableTo": "characters",
475
+ "columnsFrom": [
476
+ "character_id"
477
+ ],
478
+ "columnsTo": [
479
+ "id"
480
+ ],
481
+ "onDelete": "set null",
482
+ "onUpdate": "no action"
483
+ }
484
+ },
485
+ "compositePrimaryKeys": {},
486
+ "uniqueConstraints": {},
487
+ "policies": {},
488
+ "checkConstraints": {},
489
+ "isRLSEnabled": false
490
+ },
491
+ "public.sync_state": {
492
+ "name": "sync_state",
493
+ "schema": "",
494
+ "columns": {
495
+ "id": {
496
+ "name": "id",
497
+ "type": "uuid",
498
+ "primaryKey": true,
499
+ "notNull": true,
500
+ "default": "gen_random_uuid()"
501
+ },
502
+ "last_synced_at": {
503
+ "name": "last_synced_at",
504
+ "type": "timestamp",
505
+ "primaryKey": false,
506
+ "notNull": true,
507
+ "default": "now()"
508
+ },
509
+ "synced_by": {
510
+ "name": "synced_by",
511
+ "type": "text",
512
+ "primaryKey": false,
513
+ "notNull": false
514
+ }
515
+ },
516
+ "indexes": {},
517
+ "foreignKeys": {},
518
+ "compositePrimaryKeys": {},
519
+ "uniqueConstraints": {},
520
+ "policies": {},
521
+ "checkConstraints": {},
522
+ "isRLSEnabled": false
523
+ }
524
+ },
525
+ "enums": {
526
+ "public.link_status": {
527
+ "name": "link_status",
528
+ "schema": "public",
529
+ "values": [
530
+ "unlinked",
531
+ "linked",
532
+ "pending"
533
+ ]
534
+ },
535
+ "public.member_role": {
536
+ "name": "member_role",
537
+ "schema": "public",
538
+ "values": [
539
+ "member",
540
+ "officer",
541
+ "guildmaster"
542
+ ]
543
+ },
544
+ "public.request_status": {
545
+ "name": "request_status",
546
+ "schema": "public",
547
+ "values": [
548
+ "pending",
549
+ "approved",
550
+ "rejected"
551
+ ]
552
+ }
553
+ },
554
+ "schemas": {},
555
+ "sequences": {},
556
+ "roles": {},
557
+ "policies": {},
558
+ "views": {},
559
+ "_meta": {
560
+ "columns": {},
561
+ "schemas": {},
562
+ "tables": {}
563
+ }
564
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "postgresql",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "7",
8
+ "when": 1779227262200,
9
+ "tag": "0000_bright_tony_stark",
10
+ "breakpoints": true
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,11 @@
1
+ import type { Config } from "drizzle-kit";
2
+
3
+ export default {
4
+ schema: "./src/schema.ts",
5
+ out: "./drizzle",
6
+ dialect: "postgresql",
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL!,
9
+ ssl: true,
10
+ },
11
+ } satisfies Config;
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@ravxd/velocitydb",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./src/index.ts"
7
+ },
8
+ "scripts": {
9
+ "db:generate": "drizzle-kit generate",
10
+ "db:migrate": "drizzle-kit migrate",
11
+ "db:push": "drizzle-kit push",
12
+ "db:studio": "drizzle-kit studio"
13
+ },
14
+ "dependencies": {
15
+ "date-fns": "^4.2.1"
16
+ },
17
+ "peerDependencies": {
18
+ "drizzle-orm": "^0.45.2",
19
+ "postgres": "^3.4.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^25.9.1",
23
+ "drizzle-kit": "^0.31.0",
24
+ "drizzle-orm": "^0.45.2",
25
+ "postgres": "^3.4.0",
26
+ "typescript": "^5.8.0"
27
+ }
28
+ }
package/src/client.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { drizzle } from "drizzle-orm/postgres-js";
2
+ import postgres from "postgres";
3
+ import * as schema from "./schema";
4
+
5
+ let _db: ReturnType<typeof drizzle<typeof schema>> | null = null;
6
+
7
+ export function getDb() {
8
+ if (_db) return _db;
9
+
10
+ const connectionString = process.env.DATABASE_URL;
11
+ if (!connectionString) {
12
+ throw new Error("DATABASE_URL environment variable is not set");
13
+ }
14
+
15
+ const client = postgres(connectionString, {
16
+ max: 10,
17
+ idle_timeout: 20,
18
+ connect_timeout: 10,
19
+ });
20
+
21
+ _db = drizzle(client, { schema });
22
+ return _db;
23
+ }
24
+
25
+ export type Db = ReturnType<typeof getDb>;
package/src/helpers.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Returns the most recent Wednesday (midnight UTC) on or before the given date.
3
+ * This is the "week start" for our Wed–Tue raid tracking cycle.
4
+ */
5
+ export function getWeekStart(date: Date = new Date()): Date {
6
+ const d = new Date(date);
7
+ d.setUTCHours(0, 0, 0, 0);
8
+ // getUTCDay: 0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri, 6=Sat
9
+ const day = d.getUTCDay();
10
+ // Days since last Wednesday: Wed=0, Thu=1, Fri=2, Sat=3, Sun=4, Mon=5, Tue=6
11
+ const daysSinceWed = (day + 4) % 7;
12
+ d.setUTCDate(d.getUTCDate() - daysSinceWed);
13
+ return d;
14
+ }
15
+
16
+ /**
17
+ * Formats a week start date as an ISO date string (YYYY-MM-DD) for DB storage.
18
+ */
19
+ export function weekStartToString(date: Date): string {
20
+ return date.toISOString().split("T")[0];
21
+ }
22
+
23
+ /**
24
+ * Returns the week start string for a given date (or today).
25
+ */
26
+ export function getCurrentWeekStart(date?: Date): string {
27
+ return weekStartToString(getWeekStart(date));
28
+ }
29
+
30
+ /**
31
+ * Returns a display label for a week range: "Wed May 21 – Tue May 27"
32
+ */
33
+ export function formatWeekRange(weekStart: Date | string): string {
34
+ const start = typeof weekStart === "string" ? new Date(weekStart + "T00:00:00Z") : weekStart;
35
+ const end = new Date(start);
36
+ end.setUTCDate(end.getUTCDate() + 6);
37
+ const fmt = new Intl.DateTimeFormat("en-US", {
38
+ month: "short",
39
+ day: "numeric",
40
+ timeZone: "UTC",
41
+ });
42
+ return `${fmt.format(start)} – ${fmt.format(end)}`;
43
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./schema";
2
+ export * from "./client";
3
+ export * from "./helpers";
package/src/schema.ts ADDED
@@ -0,0 +1,142 @@
1
+ import {
2
+ pgTable,
3
+ text,
4
+ boolean,
5
+ date,
6
+ timestamp,
7
+ pgEnum,
8
+ uuid,
9
+ index,
10
+ } from "drizzle-orm/pg-core";
11
+
12
+ // ─── Enums ────────────────────────────────────────────────────────────────────
13
+
14
+ export const memberRoleEnum = pgEnum("member_role", [
15
+ "member",
16
+ "officer",
17
+ "guildmaster",
18
+ ]);
19
+
20
+ export const linkStatusEnum = pgEnum("link_status", [
21
+ "unlinked",
22
+ "linked",
23
+ "pending", // picked from unclaimed list, awaiting admin approval — reserved for future use
24
+ ]);
25
+
26
+ export const requestStatusEnum = pgEnum("request_status", [
27
+ "pending",
28
+ "approved",
29
+ "rejected",
30
+ ]);
31
+
32
+ // ─── Members ──────────────────────────────────────────────────────────────────
33
+
34
+ export const members = pgTable(
35
+ "members",
36
+ {
37
+ id: uuid("id").primaryKey().defaultRandom(),
38
+ discordId: text("discord_id").notNull().unique(),
39
+ discordUsername: text("discord_username").notNull(),
40
+ displayName: text("display_name").notNull(),
41
+ battletag: text("battletag"),
42
+ role: memberRoleEnum("role").notNull().default("member"),
43
+ isAdmin: boolean("is_admin").notNull().default(false),
44
+
45
+ // WoWUtils link
46
+ wowutilsMemberId: text("wowutils_member_id").unique(),
47
+ wowutilsAlias: text("wowutils_alias"),
48
+ wowutilsRank: text("wowutils_rank"),
49
+ wowutilsMainRole: text("wowutils_main_role"),
50
+ linkStatus: linkStatusEnum("link_status").notNull().default("unlinked"),
51
+
52
+ createdAt: timestamp("created_at").notNull().defaultNow(),
53
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
54
+ },
55
+ (t) => [index("members_discord_id_idx").on(t.discordId)]
56
+ );
57
+
58
+ // ─── Characters ───────────────────────────────────────────────────────────────
59
+
60
+ export const characters = pgTable(
61
+ "characters",
62
+ {
63
+ id: uuid("id").primaryKey().defaultRandom(),
64
+ memberId: uuid("member_id")
65
+ .notNull()
66
+ .references(() => members.id, { onDelete: "cascade" }),
67
+
68
+ name: text("name").notNull(),
69
+ realm: text("realm").notNull(),
70
+ class: text("class").notNull(),
71
+ spec: text("spec").notNull(),
72
+ status: text("status").notNull().default("active"),
73
+ isMain: boolean("is_main").notNull().default(false),
74
+
75
+ // Synced from WoWUtils — null if manually added
76
+ wowutilsCharacterId: text("wowutils_character_id").unique(),
77
+
78
+ createdAt: timestamp("created_at").notNull().defaultNow(),
79
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
80
+ },
81
+ (t) => [index("characters_member_id_idx").on(t.memberId)]
82
+ );
83
+
84
+ // ─── Requests ─────────────────────────────────────────────────────────────────
85
+
86
+ // weekStart is always a Wednesday (the start of the raid tracking week).
87
+ // Helper: getWeekStart(date) → most recent Wednesday on or before date.
88
+ export const requests = pgTable(
89
+ "requests",
90
+ {
91
+ id: uuid("id").primaryKey().defaultRandom(),
92
+ memberId: uuid("member_id")
93
+ .notNull()
94
+ .references(() => members.id, { onDelete: "cascade" }),
95
+ characterId: uuid("character_id").references(() => characters.id, {
96
+ onDelete: "set null",
97
+ }),
98
+
99
+ // Denormalised snapshot in case character record changes later
100
+ characterName: text("character_name").notNull(),
101
+ classSpec: text("class_spec").notNull(),
102
+ notes: text("notes"),
103
+
104
+ weekStart: date("week_start").notNull(), // Wednesday of the tracking week
105
+ status: requestStatusEnum("status").notNull().default("pending"),
106
+
107
+ createdAt: timestamp("created_at").notNull().defaultNow(),
108
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
109
+ },
110
+ (t) => [
111
+ index("requests_week_start_idx").on(t.weekStart),
112
+ index("requests_member_id_idx").on(t.memberId),
113
+ ]
114
+ );
115
+
116
+ // ─── AFK Entries ──────────────────────────────────────────────────────────────
117
+
118
+ export const afkEntries = pgTable(
119
+ "afk_entries",
120
+ {
121
+ id: uuid("id").primaryKey().defaultRandom(),
122
+ memberId: uuid("member_id")
123
+ .notNull()
124
+ .references(() => members.id, { onDelete: "cascade" }),
125
+ afkDate: date("afk_date").notNull(),
126
+ notes: text("notes"),
127
+ createdAt: timestamp("created_at").notNull().defaultNow(),
128
+ },
129
+ (t) => [
130
+ index("afk_entries_member_id_idx").on(t.memberId),
131
+ index("afk_entries_date_idx").on(t.afkDate),
132
+ ]
133
+ );
134
+
135
+ // ─── WoWUtils Sync State ──────────────────────────────────────────────────────
136
+
137
+ // Single-row table tracking the last time the roster was synced from WoWUtils.
138
+ export const syncState = pgTable("sync_state", {
139
+ id: uuid("id").primaryKey().defaultRandom(),
140
+ lastSyncedAt: timestamp("last_synced_at").notNull().defaultNow(),
141
+ syncedBy: text("synced_by"), // discord username or "system"
142
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "noImplicitAny": false,
8
+ "skipLibCheck": true,
9
+ "outDir": "./dist",
10
+ "rootDir": "./src"
11
+ },
12
+ "include": ["src", "drizzle.config.ts"]
13
+ }