Store options in field_options with public /field-options and admin CRUD; validate learner profile values on update. Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
4.0 KiB
SQL
75 lines
4.0 KiB
SQL
CREATE TABLE IF NOT EXISTS field_options (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
field_key VARCHAR(50) NOT NULL,
|
||
code VARCHAR(50) NOT NULL,
|
||
label VARCHAR(255) NOT NULL,
|
||
display_order INT NOT NULL DEFAULT 0,
|
||
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' CHECK (status IN ('ACTIVE', 'INACTIVE')),
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ,
|
||
CONSTRAINT field_options_field_key_format CHECK (field_key ~ '^[a-z][a-z0-9_]*$'),
|
||
CONSTRAINT field_options_unique_field_code UNIQUE (field_key, code)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_field_options_field_key ON field_options(field_key);
|
||
CREATE INDEX IF NOT EXISTS idx_field_options_status ON field_options(status);
|
||
CREATE INDEX IF NOT EXISTS idx_field_options_display_order ON field_options(display_order);
|
||
|
||
INSERT INTO field_options (field_key, code, label, display_order, status) VALUES
|
||
('education_level', 'NO_FORMAL', 'No formal education', 1, 'ACTIVE'),
|
||
('education_level', 'PRIMARY', 'Primary school', 2, 'ACTIVE'),
|
||
('education_level', 'SECONDARY', 'Secondary school', 3, 'ACTIVE'),
|
||
('education_level', 'HIGH_SCHOOL', 'High school', 4, 'ACTIVE'),
|
||
('education_level', 'VOCATIONAL', 'Vocational / technical', 5, 'ACTIVE'),
|
||
('education_level', 'BACHELOR', 'Bachelor''s degree', 6, 'ACTIVE'),
|
||
('education_level', 'MASTER', 'Master''s degree', 7, 'ACTIVE'),
|
||
('education_level', 'DOCTORATE', 'Doctorate', 8, 'ACTIVE'),
|
||
('education_level', 'OTHER', 'Other', 99, 'ACTIVE'),
|
||
|
||
('occupation', 'STUDENT', 'Student', 1, 'ACTIVE'),
|
||
('occupation', 'EMPLOYED', 'Employed', 2, 'ACTIVE'),
|
||
('occupation', 'SELF_EMPLOYED', 'Self-employed', 3, 'ACTIVE'),
|
||
('occupation', 'UNEMPLOYED', 'Unemployed', 4, 'ACTIVE'),
|
||
('occupation', 'HOMEMAKER', 'Homemaker', 5, 'ACTIVE'),
|
||
('occupation', 'RETIRED', 'Retired', 6, 'ACTIVE'),
|
||
('occupation', 'OTHER', 'Other', 99, 'ACTIVE'),
|
||
|
||
('age_group', 'UNDER_13', 'Under 13', 1, 'ACTIVE'),
|
||
('age_group', '13_17', '13–17', 2, 'ACTIVE'),
|
||
('age_group', '18_24', '18–24', 3, 'ACTIVE'),
|
||
('age_group', '25_34', '25–34', 4, 'ACTIVE'),
|
||
('age_group', '35_44', '35–44', 5, 'ACTIVE'),
|
||
('age_group', '45_54', '45–54', 6, 'ACTIVE'),
|
||
('age_group', '55_PLUS', '55+', 7, 'ACTIVE'),
|
||
|
||
('learning_goal', 'EVERYDAY_CONVERSATION', 'Everyday conversation', 1, 'ACTIVE'),
|
||
('learning_goal', 'WORK_CAREER', 'Work and career', 2, 'ACTIVE'),
|
||
('learning_goal', 'ACADEMIC_STUDY', 'Academic study', 3, 'ACTIVE'),
|
||
('learning_goal', 'TRAVEL', 'Travel', 4, 'ACTIVE'),
|
||
('learning_goal', 'EXAM_PREP', 'Exam preparation', 5, 'ACTIVE'),
|
||
('learning_goal', 'PERSONAL_GROWTH', 'Personal growth', 6, 'ACTIVE'),
|
||
('learning_goal', 'OTHER', 'Other', 99, 'ACTIVE'),
|
||
|
||
('language_challange', 'PRONUNCIATION', 'Pronunciation', 1, 'ACTIVE'),
|
||
('language_challange', 'GRAMMAR', 'Grammar', 2, 'ACTIVE'),
|
||
('language_challange', 'VOCABULARY', 'Vocabulary', 3, 'ACTIVE'),
|
||
('language_challange', 'LISTENING', 'Listening', 4, 'ACTIVE'),
|
||
('language_challange', 'SPEAKING', 'Speaking confidence', 5, 'ACTIVE'),
|
||
('language_challange', 'WRITING', 'Writing', 6, 'ACTIVE'),
|
||
('language_challange', 'READING', 'Reading', 7, 'ACTIVE'),
|
||
('language_challange', 'OTHER', 'Other', 99, 'ACTIVE'),
|
||
|
||
('language_goal', 'BASIC', 'Basic communication', 1, 'ACTIVE'),
|
||
('language_goal', 'CONVERSATIONAL', 'Conversational fluency', 2, 'ACTIVE'),
|
||
('language_goal', 'PROFESSIONAL', 'Professional proficiency', 3, 'ACTIVE'),
|
||
('language_goal', 'ACADEMIC', 'Academic proficiency', 4, 'ACTIVE'),
|
||
('language_goal', 'NATIVE_LIKE', 'Near-native fluency', 5, 'ACTIVE'),
|
||
|
||
('favourite_topic', 'BUSINESS', 'Business', 1, 'ACTIVE'),
|
||
('favourite_topic', 'TECHNOLOGY', 'Technology', 2, 'ACTIVE'),
|
||
('favourite_topic', 'HEALTH', 'Health', 3, 'ACTIVE'),
|
||
('favourite_topic', 'CULTURE', 'Culture', 4, 'ACTIVE'),
|
||
('favourite_topic', 'TRAVEL', 'Travel', 5, 'ACTIVE'),
|
||
('favourite_topic', 'ENTERTAINMENT', 'Entertainment', 6, 'ACTIVE'),
|
||
('favourite_topic', 'OTHER', 'Other', 99, 'ACTIVE');
|