fix(db): anadir migraciones DDL para columnas extendidas de users, subjects y commissions
This commit is contained in:
@@ -265,7 +265,11 @@ CREATE TABLE public.commissions (
|
|||||||
created_at timestamp without time zone,
|
created_at timestamp without time zone,
|
||||||
updated_at timestamp without time zone,
|
updated_at timestamp without time zone,
|
||||||
shift character varying(30),
|
shift character varying(30),
|
||||||
virtual_link character varying(500)
|
virtual_link character varying(500),
|
||||||
|
grades_closed boolean DEFAULT false,
|
||||||
|
grades_closed_at timestamp without time zone,
|
||||||
|
grades_closed_by integer,
|
||||||
|
acta_number character varying(50)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -447,7 +451,8 @@ CREATE TABLE public.subjects (
|
|||||||
active boolean NOT NULL,
|
active boolean NOT NULL,
|
||||||
created_at timestamp without time zone,
|
created_at timestamp without time zone,
|
||||||
updated_at timestamp without time zone,
|
updated_at timestamp without time zone,
|
||||||
career_id integer
|
career_id integer,
|
||||||
|
is_short_course boolean DEFAULT false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -486,7 +491,14 @@ CREATE TABLE public.users (
|
|||||||
last_login timestamp without time zone,
|
last_login timestamp without time zone,
|
||||||
preferred_language character varying(10),
|
preferred_language character varying(10),
|
||||||
theme_preference character varying(10) DEFAULT 'auto'::character varying NOT NULL,
|
theme_preference character varying(10) DEFAULT 'auto'::character varying NOT NULL,
|
||||||
role_id integer
|
role_id integer,
|
||||||
|
first_name character varying(100),
|
||||||
|
last_name character varying(100),
|
||||||
|
phone character varying(50),
|
||||||
|
personal_email character varying(255),
|
||||||
|
address character varying(255),
|
||||||
|
document_type character varying(20) DEFAULT 'DNI'::character varying,
|
||||||
|
document_number character varying(30)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+107
-15
@@ -22,21 +22,29 @@ def init_database():
|
|||||||
|
|
||||||
# 2. Migraciones incrementales seguras para bases de datos existentes
|
# 2. Migraciones incrementales seguras para bases de datos existentes
|
||||||
if db.engine.url.drivername != 'sqlite':
|
if db.engine.url.drivername != 'sqlite':
|
||||||
|
# Columnas extendidas de users
|
||||||
db.session.execute(text("""
|
db.session.execute(text("""
|
||||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS preferred_language VARCHAR(10) DEFAULT NULL;
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS preferred_language VARCHAR(10) DEFAULT NULL;
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS theme_preference VARCHAR(10) DEFAULT 'auto' NOT NULL;
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS theme_preference VARCHAR(10) DEFAULT 'auto' NOT NULL;
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER REFERENCES roles(id) ON DELETE SET NULL;
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER REFERENCES roles(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS first_name VARCHAR(100);
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS last_name VARCHAR(100);
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS phone VARCHAR(50);
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS personal_email VARCHAR(255);
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS address VARCHAR(255);
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS document_type VARCHAR(20) DEFAULT 'DNI';
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS document_number VARCHAR(30);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_users_document_number ON users (document_number);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
# Columnas extendidas de subjects
|
||||||
db.session.execute(text("""
|
db.session.execute(text("""
|
||||||
ALTER TABLE subjects ADD COLUMN IF NOT EXISTS career_id INTEGER REFERENCES careers(id) ON DELETE SET NULL;
|
ALTER TABLE subjects ADD COLUMN IF NOT EXISTS career_id INTEGER REFERENCES careers(id) ON DELETE SET NULL;
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE subjects ALTER COLUMN code TYPE VARCHAR(50);
|
ALTER TABLE subjects ALTER COLUMN code TYPE VARCHAR(50);
|
||||||
|
ALTER TABLE subjects ADD COLUMN IF NOT EXISTS is_short_course BOOLEAN DEFAULT FALSE;
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
# Infraestructura: buildings y classrooms
|
||||||
db.session.execute(text("""
|
db.session.execute(text("""
|
||||||
CREATE TABLE IF NOT EXISTS buildings (
|
CREATE TABLE IF NOT EXISTS buildings (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -49,7 +57,26 @@ def init_database():
|
|||||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
ALTER TABLE classrooms ADD COLUMN IF NOT EXISTS building_id INTEGER REFERENCES buildings(id) ON DELETE SET NULL;
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
# Columnas extendidas de commissions
|
||||||
|
db.session.execute(text("""
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS virtual_link VARCHAR(500);
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed BOOLEAN DEFAULT FALSE;
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed_at TIMESTAMP WITHOUT TIME ZONE;
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS grades_closed_by INTEGER REFERENCES users(id) ON DELETE SET NULL;
|
||||||
|
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS acta_number VARCHAR(50);
|
||||||
|
"""))
|
||||||
|
|
||||||
|
# Columnas extendidas de reservations
|
||||||
|
db.session.execute(text("""
|
||||||
|
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
||||||
|
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS virtual_link VARCHAR(500);
|
||||||
|
"""))
|
||||||
|
|
||||||
|
# Tablas de soporte: audit_logs
|
||||||
db.session.execute(text("""
|
db.session.execute(text("""
|
||||||
CREATE TABLE IF NOT EXISTS audit_logs (
|
CREATE TABLE IF NOT EXISTS audit_logs (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -66,15 +93,8 @@ def init_database():
|
|||||||
CREATE INDEX IF NOT EXISTS ix_audit_logs_module ON audit_logs (module);
|
CREATE INDEX IF NOT EXISTS ix_audit_logs_module ON audit_logs (module);
|
||||||
CREATE INDEX IF NOT EXISTS ix_audit_logs_created_at ON audit_logs (created_at);
|
CREATE INDEX IF NOT EXISTS ix_audit_logs_created_at ON audit_logs (created_at);
|
||||||
"""))
|
"""))
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE classrooms ADD COLUMN IF NOT EXISTS building_id INTEGER REFERENCES buildings(id) ON DELETE SET NULL;
|
# Tablas de soporte: student_enrollments
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE commissions ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
|
||||||
ALTER TABLE reservations ADD COLUMN IF NOT EXISTS shift VARCHAR(30);
|
|
||||||
"""))
|
|
||||||
db.session.execute(text("""
|
db.session.execute(text("""
|
||||||
CREATE TABLE IF NOT EXISTS student_enrollments (
|
CREATE TABLE IF NOT EXISTS student_enrollments (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -89,7 +109,79 @@ def init_database():
|
|||||||
CREATE INDEX IF NOT EXISTS ix_student_enrollments_student_id ON student_enrollments (student_id);
|
CREATE INDEX IF NOT EXISTS ix_student_enrollments_student_id ON student_enrollments (student_id);
|
||||||
CREATE INDEX IF NOT EXISTS ix_student_enrollments_commission_id ON student_enrollments (commission_id);
|
CREATE INDEX IF NOT EXISTS ix_student_enrollments_commission_id ON student_enrollments (commission_id);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
# Tablas de soporte: commission_teachers
|
||||||
|
db.session.execute(text("""
|
||||||
|
CREATE TABLE IF NOT EXISTS commission_teachers (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
commission_id INTEGER NOT NULL REFERENCES commissions(id) ON DELETE CASCADE,
|
||||||
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
role VARCHAR(50) DEFAULT 'Titular' NOT NULL,
|
||||||
|
is_primary BOOLEAN DEFAULT FALSE NOT NULL,
|
||||||
|
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||||
|
CONSTRAINT uq_commission_teacher UNIQUE (commission_id, user_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_commission_teachers_commission_id ON commission_teachers (commission_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_commission_teachers_user_id ON commission_teachers (user_id);
|
||||||
|
"""))
|
||||||
|
|
||||||
|
# Tablas de soporte: system_settings
|
||||||
|
db.session.execute(text("""
|
||||||
|
CREATE TABLE IF NOT EXISTS system_settings (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
key VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
value TEXT,
|
||||||
|
description VARCHAR(255),
|
||||||
|
category VARCHAR(50) DEFAULT 'system',
|
||||||
|
is_encrypted BOOLEAN DEFAULT FALSE,
|
||||||
|
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_system_settings_key ON system_settings (key);
|
||||||
|
"""))
|
||||||
|
|
||||||
|
# Tablas de soporte: moodle_sync_tasks
|
||||||
|
db.session.execute(text("""
|
||||||
|
CREATE TABLE IF NOT EXISTS moodle_sync_tasks (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
action VARCHAR(50) NOT NULL,
|
||||||
|
entity_type VARCHAR(50) NOT NULL,
|
||||||
|
entity_id VARCHAR(100),
|
||||||
|
payload TEXT NOT NULL,
|
||||||
|
status VARCHAR(20) DEFAULT 'PENDING',
|
||||||
|
attempts INTEGER DEFAULT 0,
|
||||||
|
max_attempts INTEGER DEFAULT 5,
|
||||||
|
error_message TEXT,
|
||||||
|
next_retry_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||||
|
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_action ON moodle_sync_tasks (action);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_status ON moodle_sync_tasks (status);
|
||||||
|
CREATE INDEX IF NOT EXISTS ix_moodle_sync_tasks_next_retry_at ON moodle_sync_tasks (next_retry_at);
|
||||||
|
"""))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
cursor = db.session.connection().connection.cursor()
|
||||||
|
cursor.execute("PRAGMA table_info(users)")
|
||||||
|
existing_cols = [row[1] for row in cursor.fetchall()]
|
||||||
|
for col_name, col_def in [
|
||||||
|
('preferred_language', 'VARCHAR(10)'),
|
||||||
|
('theme_preference', "VARCHAR(10) DEFAULT 'auto'"),
|
||||||
|
('role_id', 'INTEGER'),
|
||||||
|
('first_name', 'VARCHAR(100)'),
|
||||||
|
('last_name', 'VARCHAR(100)'),
|
||||||
|
('phone', 'VARCHAR(50)'),
|
||||||
|
('personal_email', 'VARCHAR(255)'),
|
||||||
|
('address', 'VARCHAR(255)'),
|
||||||
|
('document_type', "VARCHAR(20) DEFAULT 'DNI'"),
|
||||||
|
('document_number', 'VARCHAR(30)')
|
||||||
|
]:
|
||||||
|
if col_name not in existing_cols:
|
||||||
|
cursor.execute(f"ALTER TABLE users ADD COLUMN {col_name} {col_def}")
|
||||||
|
db.session.commit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
print("[OK] Esquema y tablas actualizadas con éxito.")
|
print("[OK] Esquema y tablas actualizadas con éxito.")
|
||||||
|
|
||||||
# 3. Crear o sincronizar roles predeterminados y matriz de permisos
|
# 3. Crear o sincronizar roles predeterminados y matriz de permisos
|
||||||
|
|||||||
Reference in New Issue
Block a user