Database Schema
Tables, columns, RLS policies, and storage for Kredal. Generated from the migration SQL.
Generated file. Do not edit by hand — run
npm run docs:gen. Source:kredal-app/supabase/migrations/*.sql.
Kredal runs on Supabase Postgres. Every table has Row-Level Security enabled and is scoped to workspace membership. See the security model for the rationale and the Verify RLS runbook for testing.
Entity relationships
Tables
profiles
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
full_name | text | yes | ||
role | text | no | check: role in ('founder','consultant','admin') | |
created_at | timestamptz | no | ||
updated_at | timestamptz | no |
RLS policies: profiles_select_own (select), profiles_insert_own (insert), profiles_update_own (update).
workspaces
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
name | text | no | ||
workspace_type | text | no | check: workspace_type in ('single_company','consultant') | |
owner_user_id | uuid | no | FK → profiles | |
created_at | timestamptz | no | ||
updated_at | timestamptz | no |
RLS policies: workspaces_select_member (select), workspaces_insert_self (insert), workspaces_update_admin (update), workspaces_delete_owner (delete).
workspace_members
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
workspace_id | uuid | no | FK → workspaces | |
user_id | uuid | no | FK → profiles | |
role | text | no | check: role in ('owner','admin','member','viewer') | |
created_at | timestamptz | no |
RLS policies: workspace_members_select_member (select), workspace_members_insert (insert), workspace_members_update_admin (update), workspace_members_delete_admin (delete).
companies
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
workspace_id | uuid | no | FK → workspaces | |
legal_name | text | no | ||
trade_license_number | text | yes | ||
emirate | text | yes | ||
jurisdiction_type | text | no | check: jurisdiction_type in ('mainland','free_zone','financial_free_zone','unknown') | |
authority_name | text | yes | ||
license_activity_codes | text[] | yes | ||
incorporation_date | date | yes | ||
office_status | text | yes | ||
owner_nationality | text | yes | ||
owner_uae_residency_status | text | yes | ||
expected_monthly_turnover_aed | numeric | yes | ||
target_bank | text | yes | ||
target_account_type | text | yes | ||
status | text | no | check: status in ('draft','in_review','ready','high_risk','archived') | |
created_at | timestamptz | no | ||
updated_at | timestamptz | no |
RLS policies: companies_select_member (select), companies_insert_member (insert), companies_update_member (update), companies_delete_admin (delete).
company_owners
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
company_id | uuid | no | FK → companies | |
full_name | text | no | ||
nationality | text | yes | ||
ownership_percentage | numeric | yes | ||
is_ubo | boolean | no | ||
uae_residency_status | text | yes | ||
emirates_id_last4 | text | yes | ||
passport_country | text | yes | ||
created_at | timestamptz | no |
RLS policies: company_owners_select_member (select), company_owners_write_member (all).
documents
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
company_id | uuid | no | FK → companies | |
uploaded_by | uuid | no | FK → profiles | |
document_type | text | no | check: document_type in ( 'trade_license','moa_aoa','shareholder_register','ubo_declaration', 'owner_passport','owner_emirates_id','owner_visa','proof_of_address', 'tenancy_or_office_agreement','invoice_or_contract','bank_statement', 'source_of_funds_evidence','business_plan','company_profile','other' ) | |
storage_path | text | no | ||
original_filename | text | no | ||
mime_type | text | yes | ||
file_size_bytes | bigint | yes | ||
expiry_date | date | yes | ||
status | text | no | check: status in ('uploaded','parsed','needs_review','accepted','rejected') | |
extracted_text | text | yes | ||
parse_confidence | numeric | yes | ||
created_at | timestamptz | no | ||
updated_at | timestamptz | no |
RLS policies: documents_select_member (select), documents_write_member (all).
questionnaire_responses
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
company_id | uuid | no | FK → companies | |
section | text | no | ||
question_key | text | no | ||
answer_json | jsonb | no | ||
created_at | timestamptz | no | ||
updated_at | timestamptz | no |
RLS policies: questionnaire_select_member (select), questionnaire_write_member (all).
readiness_assessments
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
company_id | uuid | no | FK → companies | |
overall_score | integer | no | check: overall_score >= 0 and overall_score <= 100 | |
risk_level | text | no | check: risk_level in ('low','medium','high') | |
category_scores | jsonb | no | ||
flags | jsonb | no | ||
recommendations | jsonb | no | ||
scoring_version | text | no | ||
created_by | uuid | no | FK → profiles | |
created_at | timestamptz | no |
RLS policies: assessments_select_member (select), assessments_insert_member (insert).
reports
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
company_id | uuid | no | FK → companies | |
assessment_id | uuid | no | FK → readiness_assessments | |
report_type | text | no | check: report_type in ( 'founder_readiness','consultant_checklist','bank_application_pack','rejection_recovery_pack' ) | |
title | text | no | ||
content_markdown | text | no | ||
storage_path | text | yes | ||
created_by | uuid | no | FK → profiles | |
created_at | timestamptz | no |
RLS policies: reports_select_member (select), reports_insert_member (insert).
audit_events
Row-Level Security: enabled.
| Column | Type | Null | Key | Notes |
|---|---|---|---|---|
id | uuid | no | PK | |
workspace_id | uuid | yes | FK → workspaces | |
company_id | uuid | yes | FK → companies | |
user_id | uuid | no | FK → profiles | |
event_type | text | no | ||
event_data | jsonb | no | ||
created_at | timestamptz | no |
RLS policies: audit_events_insert_member (insert), audit_events_select_admin (select).
Storage
Private bucket company-documents (not public). Path convention: {workspace_id}/{company_id}/{document_id}/{filename}.
Storage RLS policies check workspace membership on the first path segment; access is only
via short-lived signed URLs generated server-side.
Generated from 10 tables.