fix(db): make ai_plans_and_limits migration idempotent
All checks were successful
build-and-release / build (cron) (push) Successful in 48s
build-and-release / build (catering-services) (push) Successful in 1m31s
build-and-release / build (companies) (push) Successful in 1m34s
build-and-release / build (developers) (push) Successful in 1m59s
build-and-release / build (customers) (push) Successful in 2m10s
build-and-release / build (employees) (push) Successful in 2m15s
build-and-release / build (gateway) (push) Successful in 59s
build-and-release / build (jobs) (push) Successful in 46s
build-and-release / build (graphic-designers) (push) Successful in 1m33s
build-and-release / build (fitness-trainers) (push) Successful in 2m44s
build-and-release / build (makeup-artists) (push) Successful in 1m53s
build-and-release / build (job-seekers) (push) Successful in 2m30s
build-and-release / build (leads) (push) Successful in 2m32s
build-and-release / build (photographers) (push) Successful in 2m33s
build-and-release / build (payments) (push) Successful in 2m53s
build-and-release / build (social-media-managers) (push) Successful in 2m38s
build-and-release / build (ugc-content-creators) (push) Successful in 2m19s
build-and-release / build (tutors) (push) Successful in 2m53s
build-and-release / build (video-editors) (push) Successful in 2m14s
build-and-release / build (users) (push) Successful in 4m35s
All checks were successful
build-and-release / build (cron) (push) Successful in 48s
build-and-release / build (catering-services) (push) Successful in 1m31s
build-and-release / build (companies) (push) Successful in 1m34s
build-and-release / build (developers) (push) Successful in 1m59s
build-and-release / build (customers) (push) Successful in 2m10s
build-and-release / build (employees) (push) Successful in 2m15s
build-and-release / build (gateway) (push) Successful in 59s
build-and-release / build (jobs) (push) Successful in 46s
build-and-release / build (graphic-designers) (push) Successful in 1m33s
build-and-release / build (fitness-trainers) (push) Successful in 2m44s
build-and-release / build (makeup-artists) (push) Successful in 1m53s
build-and-release / build (job-seekers) (push) Successful in 2m30s
build-and-release / build (leads) (push) Successful in 2m32s
build-and-release / build (photographers) (push) Successful in 2m33s
build-and-release / build (payments) (push) Successful in 2m53s
build-and-release / build (social-media-managers) (push) Successful in 2m38s
build-and-release / build (ugc-content-creators) (push) Successful in 2m19s
build-and-release / build (tutors) (push) Successful in 2m53s
build-and-release / build (video-editors) (push) Successful in 2m14s
build-and-release / build (users) (push) Successful in 4m35s
The db-migrate job (crates/db-migrate) has no applied-migrations tracking table - it replays every .sql file on every run, relying on each file being idempotent (IF NOT EXISTS / ON CONFLICT), which is the pattern virtually every other migration in this directory follows. This one wasn't: plain CREATE TABLE/CREATE INDEX and two INSERTs with no ON CONFLICT guard. Since the tables/data already exist from this file's one successful run, every subsequent migration job run failed immediately on "relation ai_plans already exists" - before ever reaching any migration after it, including ones genuinely needed (see the verification_logs FK fix two commits back). Confirmed via a live job run: this was the actual reason db-migrate had never completed successfully before. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e2635c1c30
commit
e80ce2901c
1 changed files with 23 additions and 21 deletions
|
|
@ -1,4 +1,4 @@
|
|||
CREATE TABLE ai_plans (
|
||||
CREATE TABLE IF NOT EXISTS ai_plans (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
code VARCHAR(50) UNIQUE NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
|
|
@ -11,7 +11,7 @@ CREATE TABLE ai_plans (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE user_ai_subscriptions (
|
||||
CREATE TABLE IF NOT EXISTS user_ai_subscriptions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
plan_id UUID NOT NULL REFERENCES ai_plans(id),
|
||||
|
|
@ -28,7 +28,7 @@ CREATE TABLE user_ai_subscriptions (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_feature_costs (
|
||||
CREATE TABLE IF NOT EXISTS ai_feature_costs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
feature_code VARCHAR(100) UNIQUE NOT NULL,
|
||||
display_name VARCHAR(150) NOT NULL,
|
||||
|
|
@ -41,7 +41,7 @@ CREATE TABLE ai_feature_costs (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_usage_logs (
|
||||
CREATE TABLE IF NOT EXISTS ai_usage_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
role_code VARCHAR(50),
|
||||
|
|
@ -57,7 +57,7 @@ CREATE TABLE ai_usage_logs (
|
|||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_credit_transactions (
|
||||
CREATE TABLE IF NOT EXISTS ai_credit_transactions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
transaction_type VARCHAR(50) NOT NULL,
|
||||
|
|
@ -69,7 +69,7 @@ CREATE TABLE ai_credit_transactions (
|
|||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_auto_apply_settings (
|
||||
CREATE TABLE IF NOT EXISTS ai_auto_apply_settings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
is_enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
|
@ -86,7 +86,7 @@ CREATE TABLE ai_auto_apply_settings (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_auto_apply_logs (
|
||||
CREATE TABLE IF NOT EXISTS ai_auto_apply_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
job_id UUID NOT NULL,
|
||||
|
|
@ -98,7 +98,7 @@ CREATE TABLE ai_auto_apply_logs (
|
|||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_auto_request_settings (
|
||||
CREATE TABLE IF NOT EXISTS ai_auto_request_settings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
professional_role_code VARCHAR(50) NOT NULL,
|
||||
|
|
@ -114,7 +114,7 @@ CREATE TABLE ai_auto_request_settings (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE ai_auto_request_logs (
|
||||
CREATE TABLE IF NOT EXISTS ai_auto_request_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
requirement_id UUID NOT NULL,
|
||||
|
|
@ -126,22 +126,23 @@ CREATE TABLE ai_auto_request_logs (
|
|||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_user_ai_subscriptions_user_id ON user_ai_subscriptions(user_id);
|
||||
CREATE INDEX idx_user_ai_subscriptions_plan_id ON user_ai_subscriptions(plan_id);
|
||||
CREATE INDEX idx_ai_usage_logs_user_id ON ai_usage_logs(user_id);
|
||||
CREATE INDEX idx_ai_usage_logs_feature_code ON ai_usage_logs(feature_code);
|
||||
CREATE INDEX idx_ai_usage_logs_created_at ON ai_usage_logs(created_at);
|
||||
CREATE INDEX idx_ai_credit_transactions_user_id ON ai_credit_transactions(user_id);
|
||||
CREATE INDEX idx_ai_auto_apply_logs_user_id ON ai_auto_apply_logs(user_id);
|
||||
CREATE INDEX idx_ai_auto_apply_logs_job_id ON ai_auto_apply_logs(job_id);
|
||||
CREATE INDEX idx_ai_auto_request_logs_user_id ON ai_auto_request_logs(user_id);
|
||||
CREATE INDEX idx_ai_auto_request_logs_requirement_id ON ai_auto_request_logs(requirement_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_ai_subscriptions_user_id ON user_ai_subscriptions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_ai_subscriptions_plan_id ON user_ai_subscriptions(plan_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_usage_logs_user_id ON ai_usage_logs(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_usage_logs_feature_code ON ai_usage_logs(feature_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_usage_logs_created_at ON ai_usage_logs(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_credit_transactions_user_id ON ai_credit_transactions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_auto_apply_logs_user_id ON ai_auto_apply_logs(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_auto_apply_logs_job_id ON ai_auto_apply_logs(job_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_auto_request_logs_user_id ON ai_auto_request_logs(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_auto_request_logs_requirement_id ON ai_auto_request_logs(requirement_id);
|
||||
|
||||
INSERT INTO ai_plans (code, name, monthly_credits, daily_action_limit, allowed_models, allowed_features) VALUES
|
||||
('free', 'Free', 10, 3, '["askash-fast"]', '["help_answer", "platform_guidance", "form_fill", "form_validate", "jd_generate"]'),
|
||||
('pro', 'Pro', 100, 15, '["askash-fast", "askash-main"]', '["help_answer", "platform_guidance", "form_fill", "form_validate", "job_match", "auto_apply_suggest", "auto_apply_execute", "cover_letter_generate", "requirement_match", "auto_request_suggest", "auto_request_execute"]'),
|
||||
('business', 'Business', 300, 40, '["askash-fast", "askash-main"]', '["help_answer", "platform_guidance", "form_fill", "form_validate", "jd_generate", "jd_improve", "skills_extract", "candidate_match", "candidate_shortlist"]'),
|
||||
('enterprise', 'Enterprise', 50000, 999999, '["askash-fast", "askash-main"]', '["help_answer", "platform_guidance", "form_fill", "form_validate", "jd_generate", "jd_improve", "skills_extract", "candidate_match", "candidate_shortlist", "job_match", "auto_apply_suggest", "auto_apply_execute", "cover_letter_generate", "requirement_match", "auto_request_suggest", "auto_request_execute", "admin_support_reply", "admin_ticket_summary", "admin_verification_summary", "abuse_check"]');
|
||||
('enterprise', 'Enterprise', 50000, 999999, '["askash-fast", "askash-main"]', '["help_answer", "platform_guidance", "form_fill", "form_validate", "jd_generate", "jd_improve", "skills_extract", "candidate_match", "candidate_shortlist", "job_match", "auto_apply_suggest", "auto_apply_execute", "cover_letter_generate", "requirement_match", "auto_request_suggest", "auto_request_execute", "admin_support_reply", "admin_ticket_summary", "admin_verification_summary", "abuse_check"]')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
INSERT INTO ai_feature_costs (feature_code, display_name, default_model, credit_cost) VALUES
|
||||
('help_answer', 'Help Answer', 'askash-fast', 1),
|
||||
|
|
@ -163,4 +164,5 @@ INSERT INTO ai_feature_costs (feature_code, display_name, default_model, credit_
|
|||
('admin_support_reply', 'Admin Support Reply', 'askash-main', 3),
|
||||
('admin_ticket_summary', 'Admin Ticket Summary', 'askash-fast', 1),
|
||||
('admin_verification_summary', 'Admin Verification Summary', 'askash-fast', 1),
|
||||
('abuse_check', 'Abuse Check', 'askash-fast', 1);
|
||||
('abuse_check', 'Abuse Check', 'askash-fast', 1)
|
||||
ON CONFLICT (feature_code) DO NOTHING;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue