diff --git a/services/discord-gateway/drizzle/migrations/0006_replace_base64_with_image_url.sql b/services/discord-gateway/drizzle/migrations/0006_replace_base64_with_image_url.sql new file mode 100644 index 0000000..13525df --- /dev/null +++ b/services/discord-gateway/drizzle/migrations/0006_replace_base64_with_image_url.sql @@ -0,0 +1,7 @@ +-- Replace base64 blob storage with uploaded image URL +-- Old base64 data is dropped; cache will refill on next occurrence via upload+URL. +ALTER TABLE "sticker_cache" ADD COLUMN "image_url" text NOT NULL DEFAULT ''; +--> statement-breakpoint +ALTER TABLE "sticker_cache" DROP COLUMN "base64"; +--> statement-breakpoint +ALTER TABLE "sticker_cache" DROP COLUMN "size"; diff --git a/services/discord-gateway/drizzle/migrations/meta/_journal.json b/services/discord-gateway/drizzle/migrations/meta/_journal.json index 70a48eb..537747c 100644 --- a/services/discord-gateway/drizzle/migrations/meta/_journal.json +++ b/services/discord-gateway/drizzle/migrations/meta/_journal.json @@ -43,6 +43,13 @@ "when": 1780657801437, "tag": "0005_large_squadron_sinister", "breakpoints": true + }, + { + "idx": 6, + "version": "7", + "when": 1780900000000, + "tag": "0006_replace_base64_with_image_url", + "breakpoints": true } ] } \ No newline at end of file diff --git a/services/discord-gateway/src/shared/database/schema.ts b/services/discord-gateway/src/shared/database/schema.ts index 0c03305..bbbacf0 100644 --- a/services/discord-gateway/src/shared/database/schema.ts +++ b/services/discord-gateway/src/shared/database/schema.ts @@ -431,23 +431,23 @@ export const pgTextAnalysisCacheTable = pgTable( /** * Sticker Cache Table (PostgreSQL) - * Stores base64-encoded sticker images for fast retrieval in media moderation. - * Replaces the file-based .dat + index.json cache. + * + * Stores uploaded sticker image URLs instead of raw base64 blobs. + * Stickers are uploaded to the external upload service once and the URL is + * cached here so subsequent occurrences reuse the same URL for vision analysis. * * TTL: 7 days (enforced at query time via fetched_at) - * Eviction: LRU by fetched_at, max 100MB total + * Eviction: max 5000 entries (LRU by fetched_at) */ export const pgStickerCacheTable = pgTable( "sticker_cache", { /** Sanitized sticker name (encodeURIComponent + %→_) — primary key. */ name: pgText("name").primaryKey(), - /** Base64-encoded image data. */ - base64: pgText("base64").notNull(), + /** Uploaded image URL (tele/picser). Used directly as image_url in vision API. */ + imageUrl: pgText("image_url").notNull().default(""), /** MIME type of the image (e.g. "image/png", "image/gif"). */ mime_type: pgText("mime_type").notNull(), - /** Byte length of the base64 string (for efficient SUM() eviction queries). */ - size: pgInteger("size").notNull(), /** Epoch millis when this entry was stored. Used for TTL and LRU eviction. */ fetched_at: pgBigint("fetched_at", { mode: "number" }).notNull(), },