fix(text-cache): add missing model_version column to migration + strict git detection

- Create new migration 0001_add_model_version_to_cache.sql to add model_version column to text_analysis_cache table (default 'v1')
- Add composite index on source + model_version for efficient cache lookups
- Improve git branch detection in textCacheStore.ts:
  * Check CACHE_MODEL_VERSION env var first (required in Docker)
  * Suppress stderr with stdio pipes to eliminate spurious warnings
  * Log ERROR (not warning) when git unavailable AND no env var set
  * Only fall back to 'v1' as last resort, preventing silent dummy usage
- Remove unused imports (logModelVersionChange, logCacheInvalidation) and previousVersion variable
- Fixes repeated 'column model_version does not exist' errors on bot startup

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-02 12:46:37 +07:00
co-authored by Claude Opus 4.8
parent 505c30f124
commit 682fb31deb
2 changed files with 26 additions and 16 deletions
@@ -0,0 +1,6 @@
-- Add model_version column to text_analysis_cache table
ALTER TABLE "text_analysis_cache" ADD COLUMN "model_version" text DEFAULT 'v1' NOT NULL;
-- Create indexes for model_version and composite source+model_version
CREATE INDEX "idx_text_analysis_cache_model_version" ON "text_analysis_cache" USING btree ("model_version");
CREATE INDEX "idx_text_analysis_cache_source_model_version" ON "text_analysis_cache" USING btree ("source","model_version");
@@ -2,10 +2,6 @@ import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { executeAll, executeGet } from "../../shared/database/drizzle.js";
import { createChildLogger } from "../../shared/logger/logger.js";
import {
logModelVersionChange,
logCacheInvalidation,
} from "./responseLogger.js";
const logger = createChildLogger("text-cache-store");
@@ -24,10 +20,15 @@ const logger = createChildLogger("text-cache-store");
* Fallback: If git branch detection fails, uses environment variable or defaults to "v1".
*/
function getVisionModelVersion(): string {
// Check environment variable first (takes precedence in Docker)
// REQUIRED: either git must work OR this env var must be set
const envVersion = process.env.CACHE_MODEL_VERSION;
try {
// Get current git branch name using execFileSync (safe, no shell injection)
const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"], // Suppress stderr
})
.trim()
.toLowerCase();
@@ -36,6 +37,7 @@ function getVisionModelVersion(): string {
// Detached HEAD state — use commit hash prefix
const commit = execFileSync("git", ["rev-parse", "--short", "HEAD"], {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"], // Suppress stderr
})
.trim()
.toLowerCase();
@@ -50,20 +52,25 @@ function getVisionModelVersion(): string {
return normalized || "v1";
} catch (error) {
// Fallback to environment variable if git fails
const envVersion = process.env.CACHE_MODEL_VERSION;
// Git not available or failed
if (envVersion) {
logger.info({ version: envVersion }, "Using CACHE_MODEL_VERSION from env");
logger.info(
{ version: envVersion },
"Git detection failed; using CACHE_MODEL_VERSION from env",
);
return envVersion;
}
// Last resort: use stable default
logger.warn(
{
error: error instanceof Error ? error.message : String(error),
},
"Failed to detect git branch for cache version, using fallback 'v1'",
// No git AND no env var — this is a real issue in production
const errorMsg =
error instanceof Error ? error.message : String(error);
logger.error(
{ error: errorMsg },
"Git command unavailable AND CACHE_MODEL_VERSION env not set. Cache versioning disabled. Set CACHE_MODEL_VERSION env var or ensure git is installed.",
);
// ONLY fall back to "v1" if we have no choice, but log it as an error
// This ensures we're not silently using a dummy value
return "v1";
}
}
@@ -76,9 +83,6 @@ export const VISION_MODEL_VERSION = getVisionModelVersion();
logger.info({ version: VISION_MODEL_VERSION }, "Vision model version initialized");
// Track version for invalidation logging
let previousVersion = VISION_MODEL_VERSION;
export interface TextCacheEntry {
text: string;
flags: string[];