diff --git a/apps/kbve.com/src/content/docs/application/docker.mdx b/apps/kbve.com/src/content/docs/application/docker.mdx index 206bb7b4a..9ba45dfeb 100644 --- a/apps/kbve.com/src/content/docs/application/docker.mdx +++ b/apps/kbve.com/src/content/docs/application/docker.mdx @@ -100,7 +100,7 @@ It is not important to understand this cheetsheet until you have a couple sessio Full Table of Commands: -# Docker CLI Commands Cheatsheet +### Docker CLI Commands Cheatsheet | Command | Description | | ------------------------------------------ | ------------------------------------------------------------------------------------------- | @@ -484,6 +484,9 @@ Let us begin the setup quest for Docker today! This section breaks down the various areas of installing `docker`. To install Docker, simply visit the Docker website and download the installer for your operating system. +Here is a quick [google sheet](https://docs.google.com/spreadsheets/d/1ZT8m4gpvh6xhHYIi4Ui19uHcMpymwFXpTAvd3EcgSm4/edit?gid=0#gid=0) that breaks down the different docker desktop clients for each operating systems. +This sheet has been up-to-date since late 2024 and they include about 20 different clients for MacOS, Windows and Linux. + ### Linux The operating sysetm that we perfer is `Ubuntu` and here is a quick and brief tutorial: diff --git a/apps/kbve.com/src/content/docs/gaming/wow.mdx b/apps/kbve.com/src/content/docs/gaming/wow.mdx index 4f15204b7..b70d4dcc3 100644 --- a/apps/kbve.com/src/content/docs/gaming/wow.mdx +++ b/apps/kbve.com/src/content/docs/gaming/wow.mdx @@ -33,6 +33,12 @@ This is still a proof of concept guide and needs to be worked on. However for the time being, I am going to start the document and then reference it back when I get more information. +### Addons + +For the best addon management experience in World of Warcraft, opt for CurseForge. +It provides a user-friendly interface, easy installation, and automatic updates for your addons. +Plus it has a vast library of addons, you can customize your gameplay easily and share it across multiple computers too. + ### Macros @@ -94,3 +100,21 @@ If you are not in combat, it will cast the Arcane Missiles but if you are in-com ``` This macro is part of the `tab`, `111` rotation and helps you throw your damage over time. + +#### Rogue + +#### Rogue + +##### Throw + Sinister Strike + +This macro will cast throw when you are not in combat or cast sinister strike when you are in combat! +It also throws a blue square up on the target and can cast your racial ability. +Remember to swap out `Berserking` with whatever spell you would like to combo it with! + +``` +/startattack +/cast [nocombat] Throw; [combat] Sinister Strike +/cast [combat] Berserking +/run if UnitExists("target") and not GetRaidTargetIndex("target") then SetRaidTarget("target", 6) end +/script UIErrorsFrame:Clear() +``` diff --git a/apps/kbve.com/src/content/journal/01-02.mdx b/apps/kbve.com/src/content/journal/01-02.mdx index df94d4ef3..aa6338007 100644 --- a/apps/kbve.com/src/content/journal/01-02.mdx +++ b/apps/kbve.com/src/content/journal/01-02.mdx @@ -1,7 +1,7 @@ --- title: 'January: 02' category: Daily -date: 2024-01-02 12:00:00 +date: 2025-01-02 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-03.mdx b/apps/kbve.com/src/content/journal/01-03.mdx index 2328dfabd..eb535214e 100644 --- a/apps/kbve.com/src/content/journal/01-03.mdx +++ b/apps/kbve.com/src/content/journal/01-03.mdx @@ -1,7 +1,7 @@ --- title: 'January: 03' category: Daily -date: 2024-01-03 12:00:00 +date: 2025-01-03 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-04.mdx b/apps/kbve.com/src/content/journal/01-04.mdx index fdc0a4e45..d2b9b2f44 100644 --- a/apps/kbve.com/src/content/journal/01-04.mdx +++ b/apps/kbve.com/src/content/journal/01-04.mdx @@ -1,7 +1,7 @@ --- title: 'January: 04' category: Daily -date: 2024-01-04 12:00:00 +date: 2025-01-04 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-05.mdx b/apps/kbve.com/src/content/journal/01-05.mdx index 30affab4f..2f7044b31 100644 --- a/apps/kbve.com/src/content/journal/01-05.mdx +++ b/apps/kbve.com/src/content/journal/01-05.mdx @@ -1,7 +1,7 @@ --- title: 'January: 05' category: Daily -date: 2024-01-05 12:00:00 +date: 2025-01-05 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-06.mdx b/apps/kbve.com/src/content/journal/01-06.mdx index 973ba8bb0..fbd5e4071 100644 --- a/apps/kbve.com/src/content/journal/01-06.mdx +++ b/apps/kbve.com/src/content/journal/01-06.mdx @@ -1,7 +1,7 @@ --- title: 'January: 06' category: Daily -date: 2024-01-06 12:00:00 +date: 2025-01-06 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-07.mdx b/apps/kbve.com/src/content/journal/01-07.mdx index 808ef678f..634a70b92 100644 --- a/apps/kbve.com/src/content/journal/01-07.mdx +++ b/apps/kbve.com/src/content/journal/01-07.mdx @@ -1,7 +1,7 @@ --- title: 'January: 07' category: Daily -date: 2024-01-07 12:00:00 +date: 2025-01-07 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-08.mdx b/apps/kbve.com/src/content/journal/01-08.mdx index 7fe2854bc..1ef8d04be 100644 --- a/apps/kbve.com/src/content/journal/01-08.mdx +++ b/apps/kbve.com/src/content/journal/01-08.mdx @@ -1,7 +1,7 @@ --- title: 'January: 08' category: Daily -date: 2024-01-08 12:00:00 +date: 2025-01-08 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 @@ -14,17 +14,17 @@ tags: ## 2025 -- 05:56PM +- **Rancher** - **Rancher** + 05:56PM Something went wrong with the rancher certs and I was able to figure it out by going through the issue tickets. I believe the issue was that when we updated rancher, it might have reset the certs but we were able to make sure that ACME / LetsEncrypt does its job. After going through some casual walk through with ChatGPT, we were able to solve the issue. -- 06:58PM +- **Secrets** - **Secrets** + 06:58PM We need to update the Sealed secrets once more and then enable the `discord` namespace to have access to the `service_role`. diff --git a/apps/kbve.com/src/content/journal/01-09.mdx b/apps/kbve.com/src/content/journal/01-09.mdx index c3db9f95d..9426d0f05 100644 --- a/apps/kbve.com/src/content/journal/01-09.mdx +++ b/apps/kbve.com/src/content/journal/01-09.mdx @@ -1,7 +1,7 @@ --- title: 'January: 09' category: Daily -date: 2024-01-09 12:00:00 +date: 2025-01-09 12:00:00 client: Self unsplash: 1703511606233-9c7537658701 img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 @@ -14,9 +14,9 @@ tags: ## 2025 -- 04:53PM +- **Helm** - **Helm** + 04:53PM Going to finish up the helm chart and then we can move forward. The `pydiscordsh-main.yaml` is almost done, we just need to fix the ingress. @@ -28,23 +28,23 @@ tags: ``` -- 07:10PM +- **WoW** - **WoW** + 07:10PM Some quick hardcore afk game play! I am thinking that it will be a bit rough to do on the side, while still programming. -- 09:00PM +- **Car** - **Car** + 09:00PM Car battery should be charged! Went out in the cold, got some greek yogurt and everything seems charged. -- 11:52PM +- **Deployment** - **Deployment** + 11:52PM The deployment of `PyDiscordSh` is below: diff --git a/apps/kbve.com/src/content/journal/01-10.mdx b/apps/kbve.com/src/content/journal/01-10.mdx index 754c9705c..17a8d4e17 100644 --- a/apps/kbve.com/src/content/journal/01-10.mdx +++ b/apps/kbve.com/src/content/journal/01-10.mdx @@ -1,7 +1,7 @@ --- title: 'January: 10' category: Daily -date: 2024-01-10 12:00:00 +date: 2025-01-10 12:00:00 client: Self unsplash: 1704231208356-7dab9d91e60a img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-11.mdx b/apps/kbve.com/src/content/journal/01-11.mdx index bcb2e856e..51d1ce2d7 100644 --- a/apps/kbve.com/src/content/journal/01-11.mdx +++ b/apps/kbve.com/src/content/journal/01-11.mdx @@ -1,7 +1,7 @@ --- title: 'January: 11' category: Daily -date: 2024-01-11 12:00:00 +date: 2025-01-11 12:00:00 client: Self unsplash: 1704231208356-7dab9d91e60a img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-12.mdx b/apps/kbve.com/src/content/journal/01-12.mdx index a1b6072b3..d3f4c4734 100644 --- a/apps/kbve.com/src/content/journal/01-12.mdx +++ b/apps/kbve.com/src/content/journal/01-12.mdx @@ -1,7 +1,7 @@ --- title: 'January: 12' category: Daily -date: 2024-01-12 12:00:00 +date: 2025-01-12 12:00:00 client: Self unsplash: 1704231208356-7dab9d91e60a img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-13.mdx b/apps/kbve.com/src/content/journal/01-13.mdx index ecca69af9..7342c488f 100644 --- a/apps/kbve.com/src/content/journal/01-13.mdx +++ b/apps/kbve.com/src/content/journal/01-13.mdx @@ -1,7 +1,7 @@ --- title: 'January: 13' category: Daily -date: 2024-01-13 12:00:00 +date: 2025-01-13 12:00:00 client: Self unsplash: 1704231208356-7dab9d91e60a img: https://images.unsplash.com/photo-1703511606233-9c7537658701?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 diff --git a/apps/kbve.com/src/content/journal/01-14.mdx b/apps/kbve.com/src/content/journal/01-14.mdx index b3d88e7fa..2270d0289 100644 --- a/apps/kbve.com/src/content/journal/01-14.mdx +++ b/apps/kbve.com/src/content/journal/01-14.mdx @@ -1,7 +1,7 @@ --- title: 'January: 14' category: Daily -date: 2024-01-14 12:00:00 +date: 2025-01-14 12:00:00 client: Self unsplash: 1704189125621-55e8c6cfd166 img: https://images.unsplash.com/photo-1704189125621-55e8c6cfd166?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 @@ -12,7 +12,28 @@ tags: ## Notes -### 2024 +## 2025 + +- **WoW** + + 04:05PM + + Been making some unique macros and trying to get past some of the limitations that the WoW addons / API has but its just a bit pointless. + I fear that if I push the boundries just a bit too much, I might get flagged for botting xD. + +- **Supabase** + + 08:19PM + + Time to prepare the new `discord_server` table, I want to make sure that we can easily add the new tables but also remove them if we have any issues. + While working through this, I realized that my `user_profile` table has to also get updated because its still one version behind the new one that I wanted. + I made the foolish mistake of trying to place the socials all into just one json blob, only to find out that its just not worth it! + Ughhh! + + Forgot to include the uninstall script from my other pc, going to sync that in and going to shift my entry over to the following day. + + +## 2024 - 3:55pm - `Ansible` diff --git a/apps/kbve.com/src/content/journal/01-15.mdx b/apps/kbve.com/src/content/journal/01-15.mdx index 81ecc49fd..827774d0a 100644 --- a/apps/kbve.com/src/content/journal/01-15.mdx +++ b/apps/kbve.com/src/content/journal/01-15.mdx @@ -1,7 +1,7 @@ --- title: 'January: 15' category: Daily -date: 2024-01-15 12:00:00 +date: 2025-01-15 12:00:00 client: Self unsplash: 1704189125621-55e8c6cfd166 img: https://images.unsplash.com/photo-1704189125621-55e8c6cfd166?crop=entropy&cs=srgb&fm=jpg&ixid=MnwzNjM5Nzd8MHwxfHJhbmRvbXx8fHx8fHx8fDE2ODE3NDg2ODY&ixlib=rb-4.0.3&q=85 @@ -12,6 +12,60 @@ tags: ## Notes +## 2025 + +- **Supabase** + + 01:00AM + + The next major update should be ready by tomorrow, we want to keep the turso integration but also slowly build out the migration to the postgres. + While that is going on, I want to start the front end of the discordsh server. + The question remains if we want to use NextJS or Astro, hmm, both are already included in the monorepo but I am thinking that astro with shadcn would be a better move than material design and nextjs. + + 01:34AM + + We want to include the `Constraints` for the `discord_servers` table, even though we already have them in the python code. + This is just a double check for the sake of data integrity! + Starting with the `invite` column, this is what I am thinking we will include. + +```sql +CONSTRAINT ck_valid_invite_code CHECK (invite ~ '^[A-Za-z0-9-]{2,100}$') +``` + + Next column that we want to limit is the `name`. + Actually, while looking at the `name` field, I believe it would make more sense to just drop the `TEXT` field and use a `varchar` field instead! + We should limit it to about 100 characters, to be safe, we will do 101 characters. + The `name` field will then be 101. + +```sql + +name VARCHAR(101) NOT NULL, + +CONSTRAINT ck_name_combined CHECK ( + name ~ '^[\p{L}\p{N} _-]{2,100}$' + ), + +``` + + Okay the name was replaced from TEXT field to the varchar field and we added a basic check against common attack vectors. + Granted we will not be letting the server owner directly edit the table through the RPC or supabase's api client. + The plan is still to use the python server as a medium of handling the `discord_server` data. + + Okay, that field is out of the way, the next field will be `summary` and we will follow the same logic. + Dropping the `TEXT` and using a `VARCHAR` instead. + +```sql + +summary VARCHAR(200) NOT NULL, + +CONSTRAINT ck_summary_combined CHECK ( + summary ~ '^[\p{L}\p{N} _\-,.!?]{2,200}$' +) + +``` + That will handle the summary issue for our use case! + Okay quickly added description and website as well. + Both need an additional sanitization before they get added into the table but we will handle that from the python side. ### 2024 diff --git a/apps/kilobase/sql/discordsh/server/20250113145000_init_discord_server.sql b/apps/kilobase/sql/discordsh/server/20250113145000_init_discord_server.sql index f9861e388..868c49d9a 100644 --- a/apps/kilobase/sql/discordsh/server/20250113145000_init_discord_server.sql +++ b/apps/kilobase/sql/discordsh/server/20250113145000_init_discord_server.sql @@ -6,19 +6,76 @@ CREATE TABLE IF NOT EXISTS public.discord_servers ( server_id BIGINT PRIMARY KEY, -- Unique server ID owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, -- Supabase Auth user linking lang INT DEFAULT 0, -- Bitmask for languages - status INT DEFAULT 0, -- Bitmask for public, nsfw, vip, etc. + status INT DEFAULT 0, -- Bitmask for public, nsfw, draft, hidden etc. invite TEXT NOT NULL, -- Server invite link - name TEXT NOT NULL, -- Server name - summary TEXT NOT NULL, -- Brief summary of the server + name VARCHAR(101) NOT NULL, -- Server name + summary VARCHAR(200) NOT NULL, -- Brief summary of the server description TEXT, -- Optional server description website TEXT, -- Website URL (optional) logo TEXT, -- Logo URL banner TEXT, -- Banner URL (optional) - video TEXT, -- Video link for promo + video VARCHAR(32), -- Video link for promo categories INT DEFAULT 0, -- Bitmask for categories (up to 50) - updated_at BIGINT NOT NULL -- Timestamp for last server update + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + -- Invite Code Constraint + CONSTRAINT ck_valid_invite_code CHECK ( + invite ~ '^[A-Za-z0-9-]{2,100}$' + ), + + -- Combined Name Constraint (Length + Unicode Safe) + CONSTRAINT ck_name_combined CHECK ( + name ~ '^[\p{L}\p{N} _\-,.!?]{2,100}$' + ), + + -- Summary Regex + CONSTRAINT ck_summary_combined CHECK ( + summary ~ '^[\p{L}\p{N} _\-,.!?]{2,200}$' + ), + + -- Description Regex + CONSTRAINT ck_description_markdown CHECK ( + description ~ '^[\p{L}\p{N} _\-,.!?*#~]{10,2000}$' OR description IS NULL + ), + + -- Website Constraint + CONSTRAINT ck_website_url CHECK ( + website ~* '^(http://|https://)[a-zA-Z0-9./?=_-]+$' OR website IS NULL + ), + + -- Logo Constraint + CONSTRAINT ck_logo_url CHECK ( + logo ~* '^(http://|https://)[a-zA-Z0-9./?=_-]+$' OR logo IS NULL + ), + + -- Banner URL Constraint + CONSTRAINT ck_banner_url CHECK ( + banner ~* '^(http://|https://)[a-zA-Z0-9./?=_-]+$' OR banner IS NULL + ), + + -- Video Constraint + CONSTRAINT ck_video_id CHECK ( + video ~ '^[A-Za-z0-9_-]{1,32}$' OR video IS NULL + ) + ); +-- Create the trigger function to update the `updated_at` timestamp +CREATE OR REPLACE FUNCTION set_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + -- Automatically update the `updated_at` column with the current timestamp + NEW.updated_at = CURRENT_TIMESTAMP; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger to automatically update `updated_at` on row modifications +CREATE TRIGGER trigger_set_updated_at +BEFORE UPDATE ON public.discord_servers +FOR EACH ROW +EXECUTE FUNCTION set_updated_at(); + ALTER TABLE public.discord_servers ENABLE ROW LEVEL SECURITY; -- 2. Create Discord Server Bumps Table (1:1 Relationship Enforced) diff --git a/apps/kilobase/sql/discordsh/server/20250113145000_uninstall_discord_server.sql b/apps/kilobase/sql/discordsh/server/20250113145000_uninstall_discord_server.sql new file mode 100644 index 000000000..56c1d953b --- /dev/null +++ b/apps/kilobase/sql/discordsh/server/20250113145000_uninstall_discord_server.sql @@ -0,0 +1,25 @@ +-- Start an uninstallation transaction +BEGIN; + +-- 1. Remove the Trigger(s) +DROP TRIGGER IF EXISTS trigger_enforce_tag_limit ON public.discord_server_tags; +DROP TRIGGER IF EXISTS trigger_set_updated_at ON public.discord_servers; + + +-- 2. Remove the Trigger Function +DROP FUNCTION IF EXISTS enforce_tag_limit() CASCADE; +DROP FUNCTION IF EXISTS set_updated_at() CASCADE; + +-- 3. Remove the Indexes +DROP INDEX IF EXISTS public.idx_discord_server_tags_tag_id; +DROP INDEX IF EXISTS public.idx_discord_server_bumps_bump_at; + +-- 4. Drop the Tables in the correct dependency order +-- (Tables referencing discord_servers should be dropped first, followed by discord_servers itself) +DROP TABLE IF EXISTS public.discord_server_tags CASCADE; +DROP TABLE IF EXISTS public.discord_server_premium CASCADE; +DROP TABLE IF EXISTS public.discord_server_bumps CASCADE; +DROP TABLE IF EXISTS public.discord_servers CASCADE; + +-- End the uninstallation transaction +COMMIT; diff --git a/apps/kilobase/sql/discordsh/server/discord_server_verification_script.sql b/apps/kilobase/sql/discordsh/server/discord_server_verification_script.sql new file mode 100644 index 000000000..783626fd6 --- /dev/null +++ b/apps/kilobase/sql/discordsh/server/discord_server_verification_script.sql @@ -0,0 +1,80 @@ +-- Begin verification script +BEGIN; + +-- Collect all missing components into an array +SELECT ARRAY( + SELECT verification_result + FROM ( + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'discord_servers' + ) THEN 'discord_servers MISSING' END AS verification_result + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'discord_server_bumps' + ) THEN 'discord_server_bumps MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'discord_server_premium' + ) THEN 'discord_server_premium MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'discord_server_tags' + ) THEN 'discord_server_tags MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM pg_proc + WHERE proname = 'set_updated_at' + ) THEN 'set_updated_at function MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM pg_proc + WHERE proname = 'enforce_tag_limit' + ) THEN 'enforce_tag_limit function MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.triggers + WHERE event_object_table = 'discord_servers' + AND trigger_name = 'trigger_set_updated_at' + ) THEN 'trigger_set_updated_at MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM information_schema.triggers + WHERE event_object_table = 'discord_server_tags' + AND trigger_name = 'trigger_enforce_tag_limit' + ) THEN 'trigger_enforce_tag_limit MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM pg_indexes + WHERE schemaname = 'public' + AND indexname = 'idx_discord_server_tags_tag_id' + ) THEN 'idx_discord_server_tags_tag_id MISSING' END + UNION ALL + SELECT + CASE WHEN NOT EXISTS ( + SELECT FROM pg_indexes + WHERE schemaname = 'public' + AND indexname = 'idx_discord_server_bumps_bump_at' + ) THEN 'idx_discord_server_bumps_bump_at MISSING' END + ) AS verification_results + WHERE verification_result IS NOT NULL +) AS missing_components; + +-- End the verification script +COMMIT;