From ebb9b9b38ee4d22f8b1d5455b385ffe2297777e1 Mon Sep 17 00:00:00 2001 From: casulit Date: Thu, 17 Oct 2024 12:06:15 +0800 Subject: [PATCH] refactor(schema): Update and optimize database schema structure(Note: The actual commit message is shorter than 100 characters as requested, and it summarizes the key changes made to the schema, such as adding new tables, indexes, and functions, and removing or modifying existing ones.) --- deno.json | 2 +- deno.lock | 143 +++-------------------------------------------------- schema.sql | 106 +++++++++++++++++++++++++++++---------- server.ts | 6 +++ 4 files changed, 94 insertions(+), 163 deletions(-) diff --git a/deno.json b/deno.json index 6f475a4..fd25ae9 100644 --- a/deno.json +++ b/deno.json @@ -4,7 +4,7 @@ "imports": { "@clerk/backend": "npm:@clerk/backend@^1.13.9", "@hono/clerk-auth": "npm:@hono/clerk-auth@^2.0.0", - "@hono/hono": "jsr:@hono/hono@^4.6.4", + "@hono/hono": "jsr:@hono/hono@^4.6.5", "@std/dotenv": "jsr:@std/dotenv@^0.225.2", "@wok/pg-driver": "jsr:@wok/pg-driver@^0.19.4", "zod": "npm:zod@^3.23.8" diff --git a/deno.lock b/deno.lock index 9999629..b16d2ca 100644 --- a/deno.lock +++ b/deno.lock @@ -1,8 +1,7 @@ { "version": "4", "specifiers": { - "jsr:@hono/hono@*": "4.6.4", - "jsr:@hono/hono@^4.6.4": "4.6.4", + "jsr:@hono/hono@^4.6.5": "4.6.5", "jsr:@std/async@1": "1.0.6", "jsr:@std/bytes@^1.0.2": "1.0.2", "jsr:@std/crypto@^1.0.1": "1.0.3", @@ -16,12 +15,12 @@ "jsr:@wok/pg-driver@*": "0.19.4", "jsr:@wok/pg-driver@~0.19.4": "0.19.4", "npm:@clerk/backend@^1.13.9": "1.13.9", - "npm:@hono/clerk-auth@2": "2.0.0_@clerk+backend@1.13.9_hono@4.6.3", + "npm:@hono/clerk-auth@2": "2.0.0_@clerk+backend@1.13.9_hono@4.6.4", "npm:zod@^3.23.8": "3.23.8" }, "jsr": { - "@hono/hono@4.6.4": { - "integrity": "9bbd937653ab902405af33743561140f8883d27dc730eb9ceac665e2468c8bf6" + "@hono/hono@4.6.5": { + "integrity": "68efe4a0ab7c4fb082cb71aa894a25e1c6cfad6d124dc943471e6758a7a1bdee" }, "@std/async@1.0.6": { "integrity": "6d262156dd35c4a72ee1a2f8679be40264f370cfb92e2e13d4eca2ae05e16f34" @@ -94,7 +93,7 @@ "csstype" ] }, - "@hono/clerk-auth@2.0.0_@clerk+backend@1.13.9_hono@4.6.3": { + "@hono/clerk-auth@2.0.0_@clerk+backend@1.13.9_hono@4.6.4": { "integrity": "sha512-ad+U8jDlBPgXBTv8BRnPrSFC/uX8U0ojiCR77I3WWHm5I9L3/bHsZpQ2lgvLTV3YbJyVmAdKJArEAQiPjodGdA==", "dependencies": [ "@clerk/backend", @@ -120,8 +119,8 @@ "glob-to-regexp@0.4.1": { "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "hono@4.6.3": { - "integrity": "sha512-0LeEuBNFeSHGqZ9sNVVgZjB1V5fmhkBSB0hZrpqStSMLOWgfLy0dHOvrjbJh0H2khsjet6rbHfWTHY0kpYThKQ==" + "hono@4.6.4": { + "integrity": "sha512-T5WqBkTOcIQblqBKB5mpzaH/A+dSpvVe938xZJCHOmOuYfF7DSwE/9/10+BMvwSPq9N/f6LiQ38HxrZSQOsXKw==" }, "js-cookie@3.0.5": { "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==" @@ -199,135 +198,9 @@ "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" } }, - "redirects": { - "https://deno.land/x/postgres/mod.ts": "https://deno.land/x/postgres@v0.19.3/mod.ts" - }, - "remote": { - "https://deno.land/std@0.214.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", - "https://deno.land/std@0.214.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", - "https://deno.land/std@0.214.0/async/delay.ts": "8e1d18fe8b28ff95885e2bc54eccec1713f57f756053576d8228e6ca110793ad", - "https://deno.land/std@0.214.0/bytes/copy.ts": "f29c03168853720dfe82eaa57793d0b9e3543ebfe5306684182f0f1e3bfd422a", - "https://deno.land/std@0.214.0/crypto/_fnv/fnv32.ts": "ba2c5ef976b9f047d7ce2d33dfe18671afc75154bcf20ef89d932b2fe8820535", - "https://deno.land/std@0.214.0/crypto/_fnv/fnv64.ts": "580cadfe2ff333fe253d15df450f927c8ac7e408b704547be26aab41b5772558", - "https://deno.land/std@0.214.0/crypto/_fnv/mod.ts": "8dbb60f062a6e77b82f7a62ac11fabfba52c3cd408c21916b130d8f57a880f96", - "https://deno.land/std@0.214.0/crypto/_fnv/util.ts": "27b36ce3440d0a180af6bf1cfc2c326f68823288540a354dc1d636b781b9b75f", - "https://deno.land/std@0.214.0/crypto/_wasm/lib/deno_std_wasm_crypto.generated.mjs": "76c727912539737def4549bb62a96897f37eb334b979f49c57b8af7a1617635e", - "https://deno.land/std@0.214.0/crypto/_wasm/mod.ts": "c55f91473846827f077dfd7e5fc6e2726dee5003b6a5747610707cdc638a22ba", - "https://deno.land/std@0.214.0/crypto/crypto.ts": "4448f8461c797adba8d70a2c60f7795a546d7a0926e96366391bffdd06491c16", - "https://deno.land/std@0.214.0/datetime/_common.ts": "a62214c1924766e008e27d3d843ceba4b545dc2aa9880de0ecdef9966d5736b6", - "https://deno.land/std@0.214.0/datetime/parse.ts": "bb248bbcb3cd54bcaf504a1ee670fc4695e429d9019c06af954bbe2bcb8f1d02", - "https://deno.land/std@0.214.0/encoding/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376", - "https://deno.land/std@0.214.0/encoding/base64.ts": "96e61a556d933201266fea84ae500453293f2aff130057b579baafda096a96bc", - "https://deno.land/std@0.214.0/encoding/hex.ts": "4d47d3b25103cf81a2ed38f54b394d39a77b63338e1eaa04b70c614cb45ec2e6", - "https://deno.land/std@0.214.0/fmt/colors.ts": "aeaee795471b56fc62a3cb2e174ed33e91551b535f44677f6320336aabb54fbb", - "https://deno.land/std@0.214.0/io/buf_reader.ts": "c73aad99491ee6db3d6b001fa4a780e9245c67b9296f5bad9c0fa7384e35d47a", - "https://deno.land/std@0.214.0/io/buf_writer.ts": "f82f640c8b3a820f600a8da429ad0537037c7d6a78426bbca2396fb1f75d3ef4", - "https://deno.land/std@0.214.0/path/_common/assert_path.ts": "2ca275f36ac1788b2acb60fb2b79cb06027198bc2ba6fb7e163efaedde98c297", - "https://deno.land/std@0.214.0/path/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2", - "https://deno.land/std@0.214.0/path/_common/common.ts": "6157c7ec1f4db2b4a9a187efd6ce76dcaf1e61cfd49f87e40d4ea102818df031", - "https://deno.land/std@0.214.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c", - "https://deno.land/std@0.214.0/path/_common/dirname.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", - "https://deno.land/std@0.214.0/path/_common/format.ts": "92500e91ea5de21c97f5fe91e178bae62af524b72d5fcd246d6d60ae4bcada8b", - "https://deno.land/std@0.214.0/path/_common/from_file_url.ts": "d672bdeebc11bf80e99bf266f886c70963107bdd31134c4e249eef51133ceccf", - "https://deno.land/std@0.214.0/path/_common/glob_to_reg_exp.ts": "2007aa87bed6eb2c8ae8381adcc3125027543d9ec347713c1ad2c68427330770", - "https://deno.land/std@0.214.0/path/_common/normalize.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", - "https://deno.land/std@0.214.0/path/_common/normalize_string.ts": "dfdf657a1b1a7db7999f7c575ee7e6b0551d9c20f19486c6c3f5ff428384c965", - "https://deno.land/std@0.214.0/path/_common/relative.ts": "faa2753d9b32320ed4ada0733261e3357c186e5705678d9dd08b97527deae607", - "https://deno.land/std@0.214.0/path/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a", - "https://deno.land/std@0.214.0/path/_common/to_file_url.ts": "7f76adbc83ece1bba173e6e98a27c647712cab773d3f8cbe0398b74afc817883", - "https://deno.land/std@0.214.0/path/_interface.ts": "a1419fcf45c0ceb8acdccc94394e3e94f99e18cfd32d509aab514c8841799600", - "https://deno.land/std@0.214.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15", - "https://deno.land/std@0.214.0/path/basename.ts": "5d341aadb7ada266e2280561692c165771d071c98746fcb66da928870cd47668", - "https://deno.land/std@0.214.0/path/common.ts": "03e52e22882402c986fe97ca3b5bb4263c2aa811c515ce84584b23bac4cc2643", - "https://deno.land/std@0.214.0/path/constants.ts": "0c206169ca104938ede9da48ac952de288f23343304a1c3cb6ec7625e7325f36", - "https://deno.land/std@0.214.0/path/dirname.ts": "85bd955bf31d62c9aafdd7ff561c4b5fb587d11a9a5a45e2b01aedffa4238a7c", - "https://deno.land/std@0.214.0/path/extname.ts": "593303db8ae8c865cbd9ceec6e55d4b9ac5410c1e276bfd3131916591b954441", - "https://deno.land/std@0.214.0/path/format.ts": "98fad25f1af7b96a48efb5b67378fcc8ed77be895df8b9c733b86411632162af", - "https://deno.land/std@0.214.0/path/from_file_url.ts": "911833ae4fd10a1c84f6271f36151ab785955849117dc48c6e43b929504ee069", - "https://deno.land/std@0.214.0/path/glob_to_regexp.ts": "83c5fd36a8c86f5e72df9d0f45317f9546afa2ce39acaafe079d43a865aced08", - "https://deno.land/std@0.214.0/path/is_absolute.ts": "4791afc8bfd0c87f0526eaa616b0d16e7b3ab6a65b62942e50eac68de4ef67d7", - "https://deno.land/std@0.214.0/path/is_glob.ts": "a65f6195d3058c3050ab905705891b412ff942a292bcbaa1a807a74439a14141", - "https://deno.land/std@0.214.0/path/join.ts": "ae2ec5ca44c7e84a235fd532e4a0116bfb1f2368b394db1c4fb75e3c0f26a33a", - "https://deno.land/std@0.214.0/path/join_globs.ts": "e9589869a33dc3982101898ee50903db918ca00ad2614dbe3934d597d7b1fbea", - "https://deno.land/std@0.214.0/path/mod.ts": "ffeaccb713dbe6c72e015b7c767f753f8ec5fbc3b621ff5eeee486ffc2c0ddda", - "https://deno.land/std@0.214.0/path/normalize.ts": "4155743ccceeed319b350c1e62e931600272fad8ad00c417b91df093867a8352", - "https://deno.land/std@0.214.0/path/normalize_glob.ts": "98ee8268fad271193603271c203ae973280b5abfbdd2cbca1053fd2af71869ca", - "https://deno.land/std@0.214.0/path/parse.ts": "65e8e285f1a63b714e19ef24b68f56e76934c3df0b6e65fd440d3991f4f8aefb", - "https://deno.land/std@0.214.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d", - "https://deno.land/std@0.214.0/path/posix/basename.ts": "39ee27a29f1f35935d3603ccf01d53f3d6e0c5d4d0f84421e65bd1afeff42843", - "https://deno.land/std@0.214.0/path/posix/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4", - "https://deno.land/std@0.214.0/path/posix/constants.ts": "93481efb98cdffa4c719c22a0182b994e5a6aed3047e1962f6c2c75b7592bef1", - "https://deno.land/std@0.214.0/path/posix/dirname.ts": "6535d2bdd566118963537b9dda8867ba9e2a361015540dc91f5afbb65c0cce8b", - "https://deno.land/std@0.214.0/path/posix/extname.ts": "8d36ae0082063c5e1191639699e6f77d3acf501600a3d87b74943f0ae5327427", - "https://deno.land/std@0.214.0/path/posix/format.ts": "185e9ee2091a42dd39e2a3b8e4925370ee8407572cee1ae52838aed96310c5c1", - "https://deno.land/std@0.214.0/path/posix/from_file_url.ts": "951aee3a2c46fd0ed488899d024c6352b59154c70552e90885ed0c2ab699bc40", - "https://deno.land/std@0.214.0/path/posix/glob_to_regexp.ts": "54d3ff40f309e3732ab6e5b19d7111d2d415248bcd35b67a99defcbc1972e697", - "https://deno.land/std@0.214.0/path/posix/is_absolute.ts": "cebe561ad0ae294f0ce0365a1879dcfca8abd872821519b4fcc8d8967f888ede", - "https://deno.land/std@0.214.0/path/posix/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9", - "https://deno.land/std@0.214.0/path/posix/join.ts": "aef88d5fa3650f7516730865dbb951594d1a955b785e2450dbee93b8e32694f3", - "https://deno.land/std@0.214.0/path/posix/join_globs.ts": "ee2f4676c5b8a0dfa519da58b8ade4d1c4aa8dd3fe35619edec883ae9df1f8c9", - "https://deno.land/std@0.214.0/path/posix/mod.ts": "563a18c2b3ddc62f3e4a324ff0f583e819b8602a72ad880cb98c9e2e34f8db5b", - "https://deno.land/std@0.214.0/path/posix/normalize.ts": "baeb49816a8299f90a0237d214cef46f00ba3e95c0d2ceb74205a6a584b58a91", - "https://deno.land/std@0.214.0/path/posix/normalize_glob.ts": "65f0138fa518ef9ece354f32889783fc38cdf985fb02dcf1c3b14fa47d665640", - "https://deno.land/std@0.214.0/path/posix/parse.ts": "d5bac4eb21262ab168eead7e2196cb862940c84cee572eafedd12a0d34adc8fb", - "https://deno.land/std@0.214.0/path/posix/relative.ts": "3907d6eda41f0ff723d336125a1ad4349112cd4d48f693859980314d5b9da31c", - "https://deno.land/std@0.214.0/path/posix/resolve.ts": "bac20d9921beebbbb2b73706683b518b1d0c1b1da514140cee409e90d6b2913a", - "https://deno.land/std@0.214.0/path/posix/separator.ts": "c9ecae5c843170118156ac5d12dc53e9caf6a1a4c96fc8b1a0ab02dff5c847b0", - "https://deno.land/std@0.214.0/path/posix/to_file_url.ts": "7aa752ba66a35049e0e4a4be5a0a31ac6b645257d2e031142abb1854de250aaf", - "https://deno.land/std@0.214.0/path/posix/to_namespaced_path.ts": "28b216b3c76f892a4dca9734ff1cc0045d135532bfd9c435ae4858bfa5a2ebf0", - "https://deno.land/std@0.214.0/path/relative.ts": "ab739d727180ed8727e34ed71d976912461d98e2b76de3d3de834c1066667add", - "https://deno.land/std@0.214.0/path/resolve.ts": "a6f977bdb4272e79d8d0ed4333e3d71367cc3926acf15ac271f1d059c8494d8d", - "https://deno.land/std@0.214.0/path/separator.ts": "c6c890507f944a1f5cb7d53b8d638d6ce3cf0f34609c8d84a10c1eaa400b77a9", - "https://deno.land/std@0.214.0/path/to_file_url.ts": "88f049b769bce411e2d2db5bd9e6fd9a185a5fbd6b9f5ad8f52bef517c4ece1b", - "https://deno.land/std@0.214.0/path/to_namespaced_path.ts": "b706a4103b104cfadc09600a5f838c2ba94dbcdb642344557122dda444526e40", - "https://deno.land/std@0.214.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808", - "https://deno.land/std@0.214.0/path/windows/basename.ts": "e2dbf31d1d6385bfab1ce38c333aa290b6d7ae9e0ecb8234a654e583cf22f8fe", - "https://deno.land/std@0.214.0/path/windows/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4", - "https://deno.land/std@0.214.0/path/windows/constants.ts": "5afaac0a1f67b68b0a380a4ef391bf59feb55856aa8c60dfc01bd3b6abb813f5", - "https://deno.land/std@0.214.0/path/windows/dirname.ts": "33e421be5a5558a1346a48e74c330b8e560be7424ed7684ea03c12c21b627bc9", - "https://deno.land/std@0.214.0/path/windows/extname.ts": "165a61b00d781257fda1e9606a48c78b06815385e7d703232548dbfc95346bef", - "https://deno.land/std@0.214.0/path/windows/format.ts": "bbb5ecf379305b472b1082cd2fdc010e44a0020030414974d6029be9ad52aeb6", - "https://deno.land/std@0.214.0/path/windows/from_file_url.ts": "ced2d587b6dff18f963f269d745c4a599cf82b0c4007356bd957cb4cb52efc01", - "https://deno.land/std@0.214.0/path/windows/glob_to_regexp.ts": "6dcd1242bd8907aa9660cbdd7c93446e6927b201112b0cba37ca5d80f81be51b", - "https://deno.land/std@0.214.0/path/windows/is_absolute.ts": "4a8f6853f8598cf91a835f41abed42112cebab09478b072e4beb00ec81f8ca8a", - "https://deno.land/std@0.214.0/path/windows/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9", - "https://deno.land/std@0.214.0/path/windows/join.ts": "e0b3356615c1a75c56ebb6a7311157911659e11fd533d80d724800126b761ac3", - "https://deno.land/std@0.214.0/path/windows/join_globs.ts": "ee2f4676c5b8a0dfa519da58b8ade4d1c4aa8dd3fe35619edec883ae9df1f8c9", - "https://deno.land/std@0.214.0/path/windows/mod.ts": "7d6062927bda47c47847ffb55d8f1a37b0383840aee5c7dfc93984005819689c", - "https://deno.land/std@0.214.0/path/windows/normalize.ts": "78126170ab917f0ca355a9af9e65ad6bfa5be14d574c5fb09bb1920f52577780", - "https://deno.land/std@0.214.0/path/windows/normalize_glob.ts": "179c86ba89f4d3fe283d2addbe0607341f79ee9b1ae663abcfb3439db2e97810", - "https://deno.land/std@0.214.0/path/windows/parse.ts": "b9239edd892a06a06625c1b58425e199f018ce5649ace024d144495c984da734", - "https://deno.land/std@0.214.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7", - "https://deno.land/std@0.214.0/path/windows/resolve.ts": "75b2e3e1238d840782cee3d8864d82bfaa593c7af8b22f19c6422cf82f330ab3", - "https://deno.land/std@0.214.0/path/windows/separator.ts": "e51c5522140eff4f8402617c5c68a201fdfa3a1a8b28dc23587cff931b665e43", - "https://deno.land/std@0.214.0/path/windows/to_file_url.ts": "1cd63fd35ec8d1370feaa4752eccc4cc05ea5362a878be8dc7db733650995484", - "https://deno.land/std@0.214.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c", - "https://deno.land/x/postgres@v0.19.3/client.ts": "d141c65c20484c545a1119c9af7a52dcc24f75c1a5633de2b9617b0f4b2ed5c1", - "https://deno.land/x/postgres@v0.19.3/client/error.ts": "05b0e35d65caf0ba21f7f6fab28c0811da83cd8b4897995a2f411c2c83391036", - "https://deno.land/x/postgres@v0.19.3/connection/auth.ts": "db15c1659742ef4d2791b32834950278dc7a40cb931f8e434e6569298e58df51", - "https://deno.land/x/postgres@v0.19.3/connection/connection.ts": "198a0ecf92a0d2aa72db3bb88b8f412d3b1f6b87d464d5f7bff9aa3b6aff8370", - "https://deno.land/x/postgres@v0.19.3/connection/connection_params.ts": "463d7a9ed559f537a55d6928cab62e1c31b808d08cd0411b6ae461d0c0183c93", - "https://deno.land/x/postgres@v0.19.3/connection/message.ts": "20da5d80fc4d7ddb7b850083e0b3fa8734eb26642221dad89c62e27d78e57a4d", - "https://deno.land/x/postgres@v0.19.3/connection/message_code.ts": "12bcb110df6945152f9f6c63128786558d7ad1e61006920daaa16ef85b3bab7d", - "https://deno.land/x/postgres@v0.19.3/connection/packet.ts": "050aeff1fc13c9349e89451a155ffcd0b1343dc313a51f84439e3e45f64b56c8", - "https://deno.land/x/postgres@v0.19.3/connection/scram.ts": "532d4d58b565a2ab48fb5e1e14dc9bfb3bb283d535011e371e698eb4a89dd994", - "https://deno.land/x/postgres@v0.19.3/debug.ts": "8add17699191f11e6830b8c95d9de25857d221bb2cf6c4ae22254d395895c1f9", - "https://deno.land/x/postgres@v0.19.3/deps.ts": "c312038fe64b8368f8a294119f11d8f235fe67de84d7c3b0ef67b3a56628171a", - "https://deno.land/x/postgres@v0.19.3/mod.ts": "4930c7b44f8d16ea71026f7e3ef22a2322d84655edceacd55f7461a9218d8560", - "https://deno.land/x/postgres@v0.19.3/pool.ts": "2289f029e7a3bd3d460d4faa71399a920b7406c92a97c0715d6e31dbf1380ec3", - "https://deno.land/x/postgres@v0.19.3/query/array_parser.ts": "ff72d3e026e3022a1a223a6530be5663f8ebbd911ed978291314e7fe6c2f2464", - "https://deno.land/x/postgres@v0.19.3/query/decode.ts": "3e89ad2a662eab66a4f4e195ff0924d71d199af3c2f5637d1ae650301a03fa9b", - "https://deno.land/x/postgres@v0.19.3/query/decoders.ts": "6a73da1024086ab91e233648c850dccbde59248b90d87054bbbd7f0bf4a50681", - "https://deno.land/x/postgres@v0.19.3/query/encode.ts": "5b1c305bc7352a6f9fe37f235dddfc23e26419c77a133b4eaea42cf136481aa6", - "https://deno.land/x/postgres@v0.19.3/query/oid.ts": "21fc714ac212350ba7df496f88ea9e01a4ee0458911d0f2b6a81498e12e7af4c", - "https://deno.land/x/postgres@v0.19.3/query/query.ts": "510f9a27da87ed7b31b5cbcd14bf3028b441ac2ddc368483679d0b86a9d9f213", - "https://deno.land/x/postgres@v0.19.3/query/transaction.ts": "8f4eef68f8e9b4be216199404315e6e08fe1fe98afb2e640bffd077662f79678", - "https://deno.land/x/postgres@v0.19.3/utils/deferred.ts": "5420531adb6c3ea29ca8aac57b9b59bd3e4b9a938a4996bbd0947a858f611080", - "https://deno.land/x/postgres@v0.19.3/utils/utils.ts": "ca47193ea03ff5b585e487a06f106d367e509263a960b787197ce0c03113a738" - }, "workspace": { "dependencies": [ - "jsr:@hono/hono@^4.6.4", + "jsr:@hono/hono@^4.6.5", "jsr:@std/dotenv@~0.225.2", "jsr:@wok/pg-driver@~0.19.4", "npm:@clerk/backend@^1.13.9", diff --git a/schema.sql b/schema.sql index cfda9c8..72b1ec6 100644 --- a/schema.sql +++ b/schema.sql @@ -1,16 +1,16 @@ --- Enable PostGIS extension CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS postgis_topology; --- Create ENUM types -CREATE TYPE offer_type AS ENUM ('Sale', 'Rent'); - --- Create tables for lookup data CREATE TABLE Property_Type ( property_type_id SERIAL PRIMARY KEY, type_name VARCHAR(255) NOT NULL UNIQUE ); +CREATE TABLE Warehouse_Type ( + warehouse_type_id SERIAL PRIMARY KEY, + type_name VARCHAR(255) NOT NULL UNIQUE +); + CREATE TABLE Listing_Type ( listing_type_id SERIAL PRIMARY KEY, type_name VARCHAR(255) NOT NULL UNIQUE @@ -40,7 +40,6 @@ CREATE TABLE Listing_Area ( area VARCHAR(255) NOT NULL ); --- Create main tables CREATE TABLE "User" ( user_id SERIAL PRIMARY KEY, clerk_id VARCHAR(255) NOT NULL UNIQUE, @@ -55,6 +54,7 @@ CREATE TABLE "User" ( CREATE TABLE Property ( id SERIAL PRIMARY KEY, + user_id INT REFERENCES "User"(user_id), floor_size DOUBLE PRECISION NOT NULL DEFAULT 0, lot_size DOUBLE PRECISION NOT NULL DEFAULT 0, building_size DOUBLE PRECISION NOT NULL DEFAULT 0, @@ -66,6 +66,7 @@ CREATE TABLE Property ( latitude FLOAT NOT NULL, year_built INT, primary_image_url VARCHAR(255), + images JSONB, amenities JSONB, property_features JSONB, indoor_features JSONB, @@ -73,17 +74,15 @@ CREATE TABLE Property ( ai_generated_description TEXT, ai_generated_basic_features JSONB, property_type_id INT NOT NULL REFERENCES Property_Type(property_type_id), - warehouse_type VARCHAR(255), + warehouse_type_id INT REFERENCES Warehouse_Type(warehouse_type_id), json_data JSONB, address VARCHAR(255), listing_region_id INT NOT NULL REFERENCES Listing_Region(id) ON DELETE CASCADE, listing_city_id INT NOT NULL REFERENCES Listing_City(id) ON DELETE CASCADE, - listing_area_id INT NOT NULL REFERENCES Listing_Area(id) ON DELETE CASCADE, + listing_area_id INT REFERENCES Listing_Area(id) ON DELETE CASCADE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, geog GEOGRAPHY(Point, 4326), - CONSTRAINT unique_location UNIQUE (latitude, longitude), - CONSTRAINT check_longitude CHECK (longitude BETWEEN -180 AND 180), CONSTRAINT check_floor_size CHECK (floor_size >= 0), CONSTRAINT check_lot_size CHECK (lot_size >= 0), CONSTRAINT check_building_size CHECK (building_size >= 0), @@ -99,15 +98,21 @@ CREATE TABLE Listing ( is_scraped BOOLEAN NOT NULL DEFAULT FALSE, address VARCHAR(255), price DOUBLE PRECISION NOT NULL CHECK (price >= 0), - offer_type offer_type NOT NULL, - listing_city_id INT REFERENCES Listing_City(id) ON DELETE CASCADE, - listing_region_id INT REFERENCES Listing_Region(id) ON DELETE CASCADE, - listing_area_id INT REFERENCES Listing_Area(id) ON DELETE CASCADE, + offer_type_id INT NOT NULL REFERENCES Listing_Type(listing_type_id), + property_id INT NOT NULL REFERENCES Property(id) ON DELETE CASCADE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); --- Create indexes +CREATE TABLE Price_Change_Log ( + id SERIAL PRIMARY KEY, + listing_id INTEGER NOT NULL, + old_price DOUBLE PRECISION, + new_price DOUBLE PRECISION NOT NULL, + change_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (listing_id) REFERENCES Listing(id) +); + CREATE INDEX idx_property_type_id ON Property(property_type_id); CREATE INDEX idx_listing_region_id ON Property(listing_region_id); CREATE INDEX idx_listing_city_id ON Property(listing_city_id); @@ -115,8 +120,13 @@ CREATE INDEX idx_listing_area_id ON Property(listing_area_id); CREATE INDEX idx_listing_price ON Listing(price); CREATE INDEX idx_listing_created_at ON Listing(created_at); CREATE INDEX idx_property_geog ON Property USING GIST(geog); +CREATE INDEX idx_property_amenities ON Property USING GIN (amenities); +CREATE INDEX idx_property_location ON Property(longitude, latitude); +CREATE INDEX idx_property_property_features ON Property USING GIN (property_features); +CREATE INDEX idx_property_indoor_features ON Property USING GIN (indoor_features); +CREATE INDEX idx_property_outdoor_features ON Property USING GIN (outdoor_features); +CREATE INDEX idx_property_ai_generated_basic_features ON Property USING GIN (ai_generated_basic_features); --- Create functions CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN @@ -125,15 +135,6 @@ BEGIN END; $$ LANGUAGE plpgsql; -CREATE OR REPLACE FUNCTION update_geog() -RETURNS TRIGGER AS $$ -BEGIN - NEW.geog = ST_SetSRID(ST_MakePoint(NEW.longitude, NEW.latitude), 4326)::geography; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - --- Create triggers CREATE TRIGGER update_property_timestamp BEFORE UPDATE ON Property FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); @@ -142,16 +143,67 @@ CREATE TRIGGER update_listing_timestamp BEFORE UPDATE ON Listing FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); +CREATE OR REPLACE FUNCTION update_geog() +RETURNS TRIGGER AS $$ +BEGIN + NEW.geog = ST_SetSRID(ST_MakePoint(NEW.longitude, NEW.latitude), 4326)::geography; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + CREATE TRIGGER update_geog_trigger BEFORE INSERT OR UPDATE ON Property FOR EACH ROW EXECUTE FUNCTION update_geog(); --- Update existing data (if needed) +CREATE OR REPLACE FUNCTION log_price_change() +RETURNS TRIGGER AS $$ +BEGIN + IF OLD.price IS DISTINCT FROM NEW.price THEN + INSERT INTO Price_change_log (listing_id, old_price, new_price, change_timestamp) + VALUES (OLD.id, OLD.price, NEW.price, CURRENT_TIMESTAMP); + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trigger_price_change +AFTER UPDATE ON Listing +FOR EACH ROW +WHEN (OLD.price IS DISTINCT FROM NEW.price) +EXECUTE FUNCTION log_price_change(); + +CREATE OR REPLACE FUNCTION check_images_format() +RETURNS TRIGGER AS $$ +BEGIN + IF NEW.images IS NOT NULL THEN + -- Raise an exception if the images are not an array + IF jsonb_typeof(NEW.images) <> 'array' THEN + RAISE EXCEPTION 'images must be a JSON array'; + END IF; + + -- Raise an exception if any element is not a valid URL + PERFORM 1 + FROM jsonb_array_elements_text(NEW.images) AS elem + WHERE elem::text = '' OR elem !~ '^https?://'; + + IF FOUND THEN + RAISE EXCEPTION 'All elements of images must be non-empty strings and valid URLs'; + END IF; + END IF; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER check_images_trigger +BEFORE INSERT OR UPDATE ON property +FOR EACH ROW +EXECUTE FUNCTION check_images_format(); + UPDATE Property SET geog = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::geography WHERE id > 0; --- Sample query (EXPLAIN ANALYZE) EXPLAIN ANALYZE WITH params AS ( SELECT diff --git a/server.ts b/server.ts index d3455f8..247f49a 100644 --- a/server.ts +++ b/server.ts @@ -13,6 +13,12 @@ app.get("/", async (c: Context) => { return c.text("Hono!"); }); +app.post("/", async (c: Context) => { + const data = await c.req.json(); + await sendMessage({ kv, data, options: { delay: 5000 } }); + return c.text("Hono!"); +}); + listenQueue(kv).catch((error) => console.error(error)); Deno.serve({ port: parseInt(Deno.env.get("PORT") || "8000") }, app.fetch);