diff --git a/routes/settings.py b/routes/settings.py index d29bafb..4a24e42 100644 --- a/routes/settings.py +++ b/routes/settings.py @@ -116,3 +116,92 @@ def toggle_theme(): # Actually, for HTMX we might want to return something or just 200 OK. return "", 200 return "Invalid theme", 400 + +@settings.route("/database_schema", methods=["GET"]) +@login_required +def database_schema(): + """Display database schema with ERD visualization""" + # Fetch database schema information + schema_info = get_database_schema() + + if htmx: + return render_block( + environment, + "dashboard/settings/database_schema.html", + "page", + schema_info=schema_info + ) + return render_template("dashboard/settings/database_schema.html", schema_info=schema_info) + +def get_database_schema(): + """Fetch database schema information for ERD generation""" + # Get all tables + tables = db.execute(""" + SELECT + table_name, + COALESCE(obj_description((quote_ident(table_schema)||'.'||quote_ident(table_name))::regclass), '') as table_comment + FROM information_schema.tables + WHERE table_schema = 'public' + AND table_type = 'BASE TABLE' + ORDER BY table_name + """) + + schema_data = [] + + for table in tables or []: + table_name = table['table_name'] + + # Get columns for this table + columns = db.execute(""" + SELECT + column_name, + data_type, + is_nullable, + column_default, + character_maximum_length + FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = %s + ORDER BY ordinal_position + """, [table_name]) + + # Get foreign keys for this table + foreign_keys = db.execute(""" + SELECT + kcu.column_name, + ccu.table_name AS foreign_table_name, + ccu.column_name AS foreign_column_name + FROM information_schema.table_constraints AS tc + JOIN information_schema.key_column_usage AS kcu + ON tc.constraint_name = kcu.constraint_name + AND tc.table_schema = kcu.table_schema + JOIN information_schema.constraint_column_usage AS ccu + ON ccu.constraint_name = tc.constraint_name + AND ccu.table_schema = tc.table_schema + WHERE tc.constraint_type = 'FOREIGN KEY' + AND tc.table_name = %s + AND tc.table_schema = 'public' + """, [table_name]) + + # Get primary keys + primary_keys = db.execute(""" + SELECT kcu.column_name + FROM information_schema.table_constraints tc + JOIN information_schema.key_column_usage kcu + ON tc.constraint_name = kcu.constraint_name + AND tc.table_schema = kcu.table_schema + WHERE tc.constraint_type = 'PRIMARY KEY' + AND tc.table_name = %s + AND tc.table_schema = 'public' + """, [table_name]) + + pk_columns = [pk['column_name'] for pk in (primary_keys or [])] + + schema_data.append({ + 'table_name': table_name, + 'columns': columns or [], + 'foreign_keys': foreign_keys or [], + 'primary_keys': pk_columns + }) + + return schema_data diff --git a/templates/dashboard/settings/api_keys.html b/templates/dashboard/settings/api_keys.html index 0ea97b1..612db4e 100644 --- a/templates/dashboard/settings/api_keys.html +++ b/templates/dashboard/settings/api_keys.html @@ -13,6 +13,11 @@ class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer"> Export Data + + Database Schema + diff --git a/templates/dashboard/settings/database_schema.html b/templates/dashboard/settings/database_schema.html new file mode 100644 index 0000000..a50b928 --- /dev/null +++ b/templates/dashboard/settings/database_schema.html @@ -0,0 +1,156 @@ +{% extends 'dashboard.html' %} + +{% block page %} +
Visual representation of your database structure with tables and + relationships.
+
+erDiagram
+{% for table in schema_info %}
+ {{ table.table_name|upper }} {
+{% for col in table.columns %} {{ col.data_type|replace(' ', '_') }} {{ col.column_name }}{% if col.column_name in table.primary_keys %} PK{% endif %}
+{% endfor %} }
+{% endfor %}
+{% for table in schema_info %}
+{% for fk in table.foreign_keys %}
+ {{ table.table_name|upper }} }|--|| {{ fk.foreign_table_name|upper }} : "references"
+{% endfor %}
+{% endfor %}
+
+ + {{ table.columns|length }} column{{ 's' if table.columns|length != 1 else '' }} + {% if table.primary_keys %} + ยท {{ table.primary_keys|length }} PK + {% endif %} +
+ +References:
+