Skip to main content

TUASESOR Database Schema

Generated automatically from the linked Supabase database. Do not edit this file manually. Run npm run db:schema instead.

Scope

  • PostgreSQL schema: tuasesor
  • Contains structural metadata only
  • Contains no table rows, OAuth tokens, passwords, or customer records
  • Database migrations remain the historical record of schema changes

Summary

  • Tables: 17
  • Functions declared in tuasesor: 8
  • Tables with RLS enabled: 10

Table accounting_accounts

Workspace-scoped accounting account catalog used to classify expense report items.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
codetextYes--
nametextNo-NOT NULL
account_typetextNo-NOT NULL
is_activebooleanNotrueNOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "accounting_accounts_pkey": PRIMARY KEY ("id")
  • "accounting_accounts_workspace_code_key": UNIQUE ("workspace_id", "code")
  • "accounting_accounts_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE

Indexes

  • "idx_accounting_accounts_workspace_id": USING "btree" ("workspace_id")

RLS policies

  • "accounting_accounts_select_workspace_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."workspace_members" "workspace_member" WHERE (("workspace_member"."workspace_id" = "accounting_accounts"."workspace_id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Triggers

  • "trigger_accounting_accounts_updated_at": BEFORE UPDATE ON "accounting_accounts" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table business_lines

Workspace-scoped catalog for business lines used in expense reports.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
codetextYes--
nametextNo-NOT NULL
is_activebooleanNotrueNOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "business_lines_pkey": PRIMARY KEY ("id")
  • "business_lines_workspace_code_key": UNIQUE ("workspace_id", "code")
  • "business_lines_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE

Indexes

  • "idx_business_lines_workspace_id": USING "btree" ("workspace_id")

RLS policies

  • "business_lines_select_workspace_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."workspace_members" "workspace_member" WHERE (("workspace_member"."workspace_id" = "business_lines"."workspace_id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Triggers

  • "trigger_business_lines_updated_at": BEFORE UPDATE ON "business_lines" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table cost_centers

Workspace-scoped catalog for cost centers used in expense reports.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
codetextYes--
nametextNo-NOT NULL
is_activebooleanNotrueNOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "cost_centers_pkey": PRIMARY KEY ("id")
  • "cost_centers_workspace_code_key": UNIQUE ("workspace_id", "code")
  • "cost_centers_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE

Indexes

  • "idx_cost_centers_workspace_id": USING "btree" ("workspace_id")

RLS policies

  • "cost_centers_select_workspace_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."workspace_members" "workspace_member" WHERE (("workspace_member"."workspace_id" = "cost_centers"."workspace_id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Triggers

  • "trigger_cost_centers_updated_at": BEFORE UPDATE ON "cost_centers" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table document_types

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
idintegerNo-NOT NULL
codetextYes--
nametextYes--

Constraints

  • "document_types_code_key": UNIQUE ("code")
  • "document_types_pkey": PRIMARY KEY ("id")

Grants

  • ALL TO "anon"
  • ALL TO "authenticated"
  • ALL TO "service_role"

Table documents

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
nametextNo-NOT NULL
sourcetextNo-NOT NULL
external_idtextYes--
storage_pathtextYes--
web_view_linktextYes--
mime_typetextYes--
size_bytesbigintYes--
modified_timetimestamp with time zoneYes--
document_type_idintegerYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL
drive_file_idtextYes--
modified_attimestamp with time zoneYes--
providertextYes'google'::"text"-
profile_iduuidYes--
typetextYes--
drive_parent_idtextYes--
sync_statustextYes'active'::"text"-
sync_batch_iduuidYes--
web_content_linktextYes--
workspace_iduuidYes--
workspace_source_iduuidYes--
entity_typetextYes--
entity_idtextYes--

Constraints

  • "documents_document_type_id_fkey": FOREIGN KEY ("document_type_id") REFERENCES "tuasesor"."document_types"("id") DEFERRABLE
  • "documents_pkey": PRIMARY KEY ("id")
  • "documents_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE SET NULL
  • "documents_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE SET NULL
  • "documents_workspace_source_id_fkey": FOREIGN KEY ("workspace_source_id") REFERENCES "tuasesor"."workspace_sources"("id") ON DELETE SET NULL
  • "unique_drive_file": UNIQUE ("drive_file_id")
  • CONSTRAINT "check_source" CHECK (("source" = ANY (ARRAY['google_drive'::"text", 'internal_upload'::"text"])))
  • CONSTRAINT "documents_sync_status_check" CHECK (("sync_status" = ANY (ARRAY['active'::"text", 'deleted_in_drive'::"text"])))
  • CONSTRAINT "documents_type_check" CHECK (("type" = ANY (ARRAY['file'::"text", 'folder'::"text"])))

Indexes

  • "idx_documents_entity": USING "btree" ("entity_type", "entity_id")
  • "idx_documents_parent": USING "btree" ("drive_parent_id")
  • "idx_documents_sync_status": USING "btree" ("sync_status")
  • "idx_documents_type": USING "btree" ("type")
  • "idx_documents_user_id": USING "btree" ("profile_id")
  • "idx_documents_workspace_id": USING "btree" ("workspace_id")
  • "idx_documents_workspace_source_id": USING "btree" ("workspace_source_id")
  • UNIQUE "idx_documents_drive_file_id": USING "btree" ("drive_file_id") WHERE ("drive_file_id" IS NOT NULL)
  • UNIQUE "idx_documents_external_id": USING "btree" ("external_id") WHERE ("external_id" IS NOT NULL)

RLS policies

No row-level policies were detected for this table in the exported schema.

Grants

  • ALL TO "service_role"

Table expense_report_items

Individual expense lines declared inside an expense report.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
expense_report_iduuidNo-NOT NULL
business_line_iduuidYes--
cost_center_iduuidYes--
accounting_account_iduuidYes--
expense_datedateNo-NOT NULL
supplier_nametextYes--
document_type_idintegerYes--
document_numbertextYes--
total_amountnumeric(14,2)No-NOT NULL
descriptiontextYes--
additional_notestextYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "expense_report_items_accounting_account_id_fkey": FOREIGN KEY ("accounting_account_id") REFERENCES "tuasesor"."accounting_accounts"("id") ON DELETE SET NULL
  • "expense_report_items_additional_notes_length_check": CHECK ((("additional_notes" IS NULL) OR ("char_length"("additional_notes") <= 500))) NOT VALID
  • "expense_report_items_business_line_id_fkey": FOREIGN KEY ("business_line_id") REFERENCES "tuasesor"."business_lines"("id") ON DELETE SET NULL
  • "expense_report_items_cost_center_id_fkey": FOREIGN KEY ("cost_center_id") REFERENCES "tuasesor"."cost_centers"("id") ON DELETE SET NULL
  • "expense_report_items_description_length_check": CHECK ((("description" IS NULL) OR ("char_length"("description") <= 500))) NOT VALID
  • "expense_report_items_document_number_length_check": CHECK ((("document_number" IS NULL) OR ("char_length"("document_number") <= 100))) NOT VALID
  • "expense_report_items_document_type_id_fkey": FOREIGN KEY ("document_type_id") REFERENCES "tuasesor"."document_types"("id") ON DELETE SET NULL
  • "expense_report_items_expense_report_id_fkey": FOREIGN KEY ("expense_report_id") REFERENCES "tuasesor"."expense_reports"("id") ON DELETE CASCADE
  • "expense_report_items_pkey": PRIMARY KEY ("id")
  • "expense_report_items_supplier_name_length_check": CHECK ((("supplier_name" IS NULL) OR ("char_length"("supplier_name") <= 150))) NOT VALID
  • CONSTRAINT "expense_report_items_total_amount_check" CHECK (("total_amount" > (0)::numeric))

Indexes

  • "idx_expense_report_items_expense_date": USING "btree" ("expense_date")
  • "idx_expense_report_items_report_expense_date": USING "btree" ("expense_report_id", "expense_date" DESC)
  • "idx_expense_report_items_report_id": USING "btree" ("expense_report_id")

RLS policies

  • "expense_report_items_delete_draft_workspace_writers": FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."expense_reports" "expense_report" WHERE (("expense_report"."id" = "expense_report_items"."expense_report_id") AND ("expense_report"."status" = 'draft'::"text") AND "tuasesor"."can_write_workspace"("expense_report"."workspace_id")))))
  • "expense_report_items_insert_draft_workspace_writers": FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1 FROM "tuasesor"."expense_reports" "expense_report" WHERE (("expense_report"."id" = "expense_report_items"."expense_report_id") AND ("expense_report"."status" = 'draft'::"text") AND "tuasesor"."can_write_workspace"("expense_report"."workspace_id")))))
  • "expense_report_items_select_workspace_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM ("tuasesor"."expense_reports" "expense_report" JOIN "tuasesor"."workspace_members" "workspace_member" ON (("workspace_member"."workspace_id" = "expense_report"."workspace_id"))) WHERE (("expense_report"."id" = "expense_report_items"."expense_report_id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))
  • "expense_report_items_update_draft_workspace_writers": FOR UPDATE TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."expense_reports" "expense_report" WHERE (("expense_report"."id" = "expense_report_items"."expense_report_id") AND ("expense_report"."status" = 'draft'::"text") AND "tuasesor"."can_write_workspace"("expense_report"."workspace_id"))))) WITH CHECK ((EXISTS ( SELECT 1 FROM "tuasesor"."expense_reports" "expense_report" WHERE (("expense_report"."id" = "expense_report_items"."expense_report_id") AND ("expense_report"."status" = 'draft'::"text") AND "tuasesor"."can_write_workspace"("expense_report"."workspace_id")))))

Grants

  • ALL TO "service_role"
  • SELECT,INSERT,DELETE,UPDATE TO "authenticated"

Triggers

  • "trigger_expense_report_items_updated_at": BEFORE UPDATE ON "expense_report_items" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()
  • "trigger_prevent_expense_report_item_parent_change": BEFORE UPDATE OF "expense_report_id" ON "expense_report_items" FOR EACH ROW EXECUTE FUNCTION "tuasesor"."prevent_expense_report_item_parent_change"()
  • "trigger_validate_expense_report_item_catalogs": BEFORE INSERT OR UPDATE OF "expense_report_id", "business_line_id", "cost_center_id", "accounting_account_id", "document_type_id" ON "expense_report_items" FOR EACH ROW EXECUTE FUNCTION "tuasesor"."validate_expense_report_item_catalogs"()

Table expense_reports

Business domain table representing complete expense reports submitted within a workspace.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
report_numbertextNo-NOT NULL
report_yearintegerNo-NOT NULL
submitted_by_profile_iduuidYes--
statustextNo'draft'::"text"NOT NULL
submitted_attimestamp with time zoneYes--
reviewed_attimestamp with time zoneYes--
reimbursed_attimestamp with time zoneYes--
notestextYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "expense_reports_pkey": PRIMARY KEY ("id")
  • "expense_reports_submitted_by_profile_id_fkey": FOREIGN KEY ("submitted_by_profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE SET NULL
  • "expense_reports_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE
  • "expense_reports_workspace_year_report_number_key": UNIQUE ("workspace_id", "report_year", "report_number")
  • CONSTRAINT "expense_reports_report_year_check" CHECK ((("report_year" >= 2000) AND ("report_year" <= 2100)))
  • CONSTRAINT "expense_reports_status_check" CHECK (("status" = ANY (ARRAY['draft'::"text", 'submitted'::"text", 'under_review'::"text", 'approved'::"text", 'rejected'::"text", 'reimbursed'::"text", 'cancelled'::"text"])))

Indexes

  • "idx_expense_reports_report_year": USING "btree" ("report_year")
  • "idx_expense_reports_status": USING "btree" ("status")
  • "idx_expense_reports_workspace_created_at": USING "btree" ("workspace_id", "created_at" DESC)
  • "idx_expense_reports_workspace_id": USING "btree" ("workspace_id")
  • "idx_expense_reports_workspace_profile_created_at": USING "btree" ("workspace_id", "submitted_by_profile_id", "created_at" DESC) WHERE ("submitted_by_profile_id" IS NOT NULL)
  • "idx_expense_reports_workspace_status_created_at": USING "btree" ("workspace_id", "status", "created_at" DESC)

RLS policies

  • "expense_reports_insert_workspace_writers": FOR INSERT TO "authenticated" WITH CHECK ("tuasesor"."can_write_workspace"("workspace_id"))
  • "expense_reports_select_workspace_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."workspace_members" "workspace_member" WHERE (("workspace_member"."workspace_id" = "expense_reports"."workspace_id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))
  • "expense_reports_update_workspace_writers": FOR UPDATE TO "authenticated" USING ("tuasesor"."can_write_workspace"("workspace_id")) WITH CHECK ("tuasesor"."can_write_workspace"("workspace_id"))

Grants

  • ALL TO "service_role"
  • SELECT,INSERT,UPDATE TO "authenticated"

Triggers

  • "trigger_expense_reports_updated_at": BEFORE UPDATE ON "expense_reports" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table integrations

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
profile_iduuidNo-NOT NULL
providertextNo-NOT NULL
access_tokentextYes--
refresh_tokentextYes--
expires_attimestamp with time zoneYes--
created_attimestamp with time zoneNo"now"()NOT NULL
metadatajsonbYes'{}'::"jsonb"-
provider_account_idtextYes--
scopes"text"[]Yes'{}'::"text"[]-

Constraints

  • "integrations_pkey": PRIMARY KEY ("id")
  • "integrations_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE CASCADE
  • "integrations_provider_provider_account_id_key": UNIQUE ("provider", "provider_account_id")
  • "unique_user_provider": UNIQUE ("profile_id", "provider")

Indexes

  • "idx_integrations_metadata": USING "gin" ("metadata")
  • "idx_integrations_provider_account_id": USING "btree" ("provider_account_id")
  • "idx_integrations_provider_provider_account_id": USING "btree" ("provider", "provider_account_id")
  • "idx_integrations_scopes": USING "gin" ("scopes")
  • "idx_integrations_user_id": USING "btree" ("profile_id")

RLS policies

  • "integrations_delete_own_profile": FOR DELETE TO "authenticated" USING (("auth"."uid"() = "profile_id"))
  • "integrations_insert_own_profile": FOR INSERT TO "authenticated" WITH CHECK (("auth"."uid"() = "profile_id"))
  • "integrations_select_own_profile": FOR SELECT TO "authenticated" USING (("auth"."uid"() = "profile_id"))
  • "integrations_update_own_profile": FOR UPDATE TO "authenticated" USING (("auth"."uid"() = "profile_id")) WITH CHECK (("auth"."uid"() = "profile_id"))

Grants

  • ALL TO "service_role"
  • SELECT,INSERT,DELETE,UPDATE TO "authenticated"

Table normalized_documents

Structured knowledge layer used by cortexa-sdk for normalized and persistent document intelligence.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
document_iduuidYes--
sourcetextNo-NOT NULL
external_idtextNo-NOT NULL
titletextYes--
filenametextYes--
mime_typetextYes--
content_texttextYes--
metadata_jsonjsonbYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL
normalized_attimestamp with time zoneNo"now"()NOT NULL
workspace_iduuidYes--

Constraints

  • "normalized_documents_document_id_fkey": FOREIGN KEY ("document_id") REFERENCES "tuasesor"."documents"("id") ON DELETE SET NULL
  • "normalized_documents_pkey": PRIMARY KEY ("id")
  • "normalized_documents_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE SET NULL

Indexes

  • "idx_normalized_documents_external_id": USING "btree" ("external_id")
  • "idx_normalized_documents_mime_type": USING "btree" ("mime_type")
  • "idx_normalized_documents_source": USING "btree" ("source")
  • "idx_normalized_documents_workspace_id": USING "btree" ("workspace_id")

RLS policies

No row-level policies were detected for this table in the exported schema.

Grants

  • ALL TO "anon"
  • ALL TO "authenticated"
  • ALL TO "service_role"

Triggers

  • "trigger_normalized_documents_updated_at": BEFORE UPDATE ON "normalized_documents" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table profile_specialties

Many-to-many relationship between profiles and professional specialties.

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
profile_iduuidNo-NOT NULL
specialty_iduuidNo-NOT NULL
is_primarybooleanNofalseNOT NULL
years_experienceintegerYes--
metadata_jsonjsonbNo'{}'::"jsonb"NOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "profile_specialties_pkey": PRIMARY KEY ("id")
  • "profile_specialties_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE CASCADE
  • "profile_specialties_profile_id_specialty_id_key": UNIQUE ("profile_id", "specialty_id")
  • "profile_specialties_specialty_id_fkey": FOREIGN KEY ("specialty_id") REFERENCES "tuasesor"."specialties"("id") ON DELETE CASCADE

Indexes

  • "idx_profile_specialties_profile_id": USING "btree" ("profile_id")
  • "idx_profile_specialties_specialty_id": USING "btree" ("specialty_id")

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Table profiles

Application-level user profiles associated 1:1 with auth.users.

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo-NOT NULL
emailtextNo-NOT NULL
full_nametextYes--
avatar_urltextYes--
global_roletextNo'member'::"text"NOT NULL
metadata_jsonjsonbNo'{}'::"jsonb"NOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL
profile_typetextNo'member'::"text"NOT NULL
statustextNo'pending'::"text"NOT NULL

Constraints

  • "profiles_auth_user_id_fkey": FOREIGN KEY ("id") REFERENCES "auth"."users"("id") ON DELETE CASCADE
  • "profiles_email_key": UNIQUE ("email")
  • "profiles_pkey": PRIMARY KEY ("id")
  • CONSTRAINT "profiles_status_check" CHECK (("status" = ANY (ARRAY['pending'::"text", 'active'::"text", 'disabled'::"text"])))

Indexes

  • "idx_profiles_status": USING "btree" ("status")

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Table specialties

Professional specialties catalog used for marketplace identity and expertise classification.

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
codetextNo-NOT NULL
nametextNo-NOT NULL
categorytextYes--
created_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "specialties_code_key": UNIQUE ("code")
  • "specialties_pkey": PRIMARY KEY ("id")

Indexes

  • "idx_specialties_code": USING "btree" ("code")

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Table transactions

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
document_iduuidYes--
typetextNo-NOT NULL
datedateNo-NOT NULL
amountnumeric(12,2)No-NOT NULL
descriptiontextYes--
document_numbertextYes--
statustextYes'pending'::"text"-
profile_iduuidYes--
created_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "transactions_document_id_fkey": FOREIGN KEY ("document_id") REFERENCES "tuasesor"."documents"("id") DEFERRABLE
  • "transactions_pkey": PRIMARY KEY ("id")
  • "transactions_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE SET NULL
  • CONSTRAINT "check_status" CHECK (("status" = ANY (ARRAY['pending'::"text", 'reviewed'::"text"])))
  • CONSTRAINT "check_type" CHECK (("type" = ANY (ARRAY['income'::"text", 'expense'::"text"])))

Grants

  • ALL TO "anon"
  • ALL TO "authenticated"
  • ALL TO "service_role"

Table workspace_member_permissions

Granular permissions associated to workspace memberships.

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_member_iduuidNo-NOT NULL
permission_keytextNo-NOT NULL
grantedbooleanNotrueNOT NULL
metadata_jsonjsonbNo'{}'::"jsonb"NOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "workspace_member_permissions_pkey": PRIMARY KEY ("id")
  • "workspace_member_permissions_workspace_member_id_fkey": FOREIGN KEY ("workspace_member_id") REFERENCES "tuasesor"."workspace_members"("id") ON DELETE CASCADE
  • "workspace_member_permissions_workspace_member_id_permission_key": UNIQUE ("workspace_member_id", "permission_key")

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Table workspace_members

Workspace-scoped memberships and permissions associated to profiles.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
profile_iduuidNo-NOT NULL
roletextNo-NOT NULL
created_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "unique_workspace_user": UNIQUE ("workspace_id", "profile_id")
  • "workspace_members_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE CASCADE
  • "workspace_users_pkey": PRIMARY KEY ("id")
  • "workspace_users_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE
  • CONSTRAINT "check_workspace_user_role" CHECK (("role" = ANY (ARRAY['owner'::"text", 'admin'::"text", 'member'::"text", 'viewer'::"text", 'client'::"text"])))

Indexes

  • "idx_workspace_users_role": USING "btree" ("role")
  • "idx_workspace_users_user_id": USING "btree" ("profile_id")
  • "idx_workspace_users_workspace_id": USING "btree" ("workspace_id")

RLS policies

  • "workspace_members_select_own_profile": FOR SELECT TO "authenticated" USING (("profile_id" = "auth"."uid"()))

Grants

  • ALL TO "service_role"
  • SELECT TO "authenticated"

Table workspace_sources

Provider-specific documentary integrations associated to a workspace.

  • Row Level Security: not enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
workspace_iduuidNo-NOT NULL
providertextNo-NOT NULL
external_idtextNo-NOT NULL
root_pathtextYes--
metadata_jsonjsonbYes--
is_activebooleanNotrueNOT NULL
last_synced_attimestamp with time zoneYes--
profile_iduuidYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "unique_workspace_provider_external": UNIQUE ("workspace_id", "provider", "external_id")
  • "workspace_sources_pkey": PRIMARY KEY ("id")
  • "workspace_sources_profile_id_fkey": FOREIGN KEY ("profile_id") REFERENCES "tuasesor"."profiles"("id") ON DELETE SET NULL
  • "workspace_sources_workspace_id_fkey": FOREIGN KEY ("workspace_id") REFERENCES "tuasesor"."workspaces"("id") ON DELETE CASCADE

Indexes

  • "idx_workspace_sources_external_id": USING "btree" ("external_id")
  • "idx_workspace_sources_is_active": USING "btree" ("is_active")
  • "idx_workspace_sources_provider": USING "btree" ("provider")
  • "idx_workspace_sources_workspace_id": USING "btree" ("workspace_id")

Grants

  • ALL TO "anon"
  • ALL TO "authenticated"
  • ALL TO "service_role"

Triggers

  • "trigger_workspace_sources_updated_at": BEFORE UPDATE ON "workspace_sources" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Table workspaces

Operational documentary context authorized within TUASESOR.

  • Row Level Security: enabled

Columns

NameTypeNullableDefaultAdditional definition
iduuidNo"gen_random_uuid"()NOT NULL
nametextNo-NOT NULL
descriptiontextYes--
created_byuuidYes--
created_attimestamp with time zoneNo"now"()NOT NULL
updated_attimestamp with time zoneNo"now"()NOT NULL

Constraints

  • "workspaces_pkey": PRIMARY KEY ("id")

Indexes

  • "idx_workspaces_created_by": USING "btree" ("created_by")

RLS policies

  • "workspaces_select_for_members": FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1 FROM "tuasesor"."workspace_members" "workspace_member" WHERE (("workspace_member"."workspace_id" = "workspaces"."id") AND ("workspace_member"."profile_id" = "auth"."uid"())))))

Grants

  • ALL TO "anon"
  • ALL TO "authenticated"
  • ALL TO "service_role"

Triggers

  • "trigger_workspaces_updated_at": BEFORE UPDATE ON "workspaces" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"()

Functions

  • "can_write_workspace"("p_workspace_id" "uuid") RETURNS boolean LANGUAGE "sql" STABLE SECURITY DEFINER SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ SELECT auth.uid() IS NOT NULL AND p_workspace_id IS NOT NULL AND EXISTS ( SELECT 1 FROM tuasesor.workspace_members AS workspace_member WHERE workspace_member.workspace_id = p_workspace_id AND workspace_member.profile_id = auth.uid() AND workspace_member.role IN ( 'owner', 'admin', 'member' ) ); $$
  • "create_expense_report"("p_workspace_id" "uuid", "p_report_number" "text", "p_report_year" integer, "p_notes" "text", "p_items" "jsonb") RETURNS "tuasesor"."expense_reports" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ DECLARE v_profile_id uuid; v_report tuasesor.expense_reports; v_item jsonb; v_business_line_id uuid; v_cost_center_id uuid; v_accounting_account_id uuid; v_document_type_id integer; BEGIN v_profile_id := auth.uid(); IF v_profile_id IS NULL THEN RAISE EXCEPTION 'Authentication is required' USING ERRCODE = '42501'; END IF; IF p_workspace_id IS NULL THEN RAISE EXCEPTION 'workspace_id is required' USING ERRCODE = '22023'; END IF; IF NOT tuasesor.can_write_workspace(p_workspace_id) THEN RAISE EXCEPTION 'Not authorized to write in this workspace' USING ERRCODE = '42501'; END IF; IF p_report_number IS NULL OR btrim(p_report_number) = '' THEN RAISE EXCEPTION 'report_number is required' USING ERRCODE = '22023'; END IF; IF p_report_year < 2000 OR p_report_year > 2100 THEN RAISE EXCEPTION 'report_year must be between 2000 and 2100' USING ERRCODE = '22023'; END IF; IF p_items IS NULL OR jsonb_typeof(p_items) <> 'array' THEN RAISE EXCEPTION 'items must be a JSON array' USING ERRCODE = '22023'; END IF; INSERT INTO tuasesor.expense_reports ( workspace_id, report_number, report_year, submitted_by_profile_id, status, notes ) VALUES ( p_workspace_id, btrim(p_report_number), p_report_year, v_profile_id, 'draft', nullif(btrim(p_notes), '') ) RETURNING * INTO v_report; FOR v_item IN SELECT value FROM jsonb_array_elements(p_items) LOOP v_business_line_id := nullif(v_item ->> 'business_line_id', '')::uuid; v_cost_center_id := nullif(v_item ->> 'cost_center_id', '')::uuid; v_accounting_account_id := nullif(v_item ->> 'accounting_account_id', '')::uuid; v_document_type_id := nullif(v_item ->> 'document_type_id', '')::integer; IF v_business_line_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.business_lines AS business_line WHERE business_line.id = v_business_line_id AND business_line.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Business line does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF v_cost_center_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.cost_centers AS cost_center WHERE cost_center.id = v_cost_center_id AND cost_center.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Cost center does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF v_accounting_account_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.accounting_accounts AS accounting_account WHERE accounting_account.id = v_accounting_account_id AND accounting_account.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Accounting account does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF v_document_type_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.document_types AS document_type WHERE document_type.id = v_document_type_id ) THEN RAISE EXCEPTION 'Document type does not exist' USING ERRCODE = '23503'; END IF; INSERT INTO tuasesor.expense_report_items ( expense_report_id, business_line_id, cost_center_id, accounting_account_id, expense_date, supplier_name, document_type_id, document_number, total_amount, description, additional_notes ) VALUES ( v_report.id, v_business_line_id, v_cost_center_id, v_accounting_account_id, (v_item ->> 'expense_date')::date, nullif(btrim(v_item ->> 'supplier_name'), ''), v_document_type_id, nullif(btrim(v_item ->> 'document_number'), ''), (v_item ->> 'total_amount')::numeric, nullif(btrim(v_item ->> 'description'), ''), nullif(btrim(v_item ->> 'additional_notes'), '') ); END LOOP; RETURN v_report; END; $$
  • "create_expense_report_item"("p_workspace_id" "uuid", "p_expense_report_id" "uuid", "p_expense_date" "date", "p_total_amount" numeric, "p_supplier_name" "text", "p_document_type_id" integer, "p_document_number" "text", "p_description" "text", "p_business_line_id" "uuid", "p_cost_center_id" "uuid", "p_accounting_account_id" "uuid", "p_additional_notes" "text") RETURNS "tuasesor"."expense_report_items" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ DECLARE v_report tuasesor.expense_reports; v_item tuasesor.expense_report_items; BEGIN IF auth.uid() IS NULL THEN RAISE EXCEPTION 'Authentication is required' USING ERRCODE = '42501'; END IF; IF p_workspace_id IS NULL OR p_expense_report_id IS NULL THEN RAISE EXCEPTION 'Workspace and expense report are required' USING ERRCODE = '22023'; END IF; SELECT expense_report.* INTO v_report FROM tuasesor.expense_reports AS expense_report WHERE expense_report.id = p_expense_report_id AND expense_report.workspace_id = p_workspace_id; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report was not found' USING ERRCODE = 'P0002'; END IF; IF NOT tuasesor.can_write_workspace(p_workspace_id) THEN RAISE EXCEPTION 'Not authorized to write in this workspace' USING ERRCODE = '42501'; END IF; IF v_report.status <> 'draft' THEN RAISE EXCEPTION 'Expense report is not editable' USING ERRCODE = '55000'; END IF; IF p_expense_date IS NULL THEN RAISE EXCEPTION 'expense_date is required' USING ERRCODE = '22023'; END IF; IF p_total_amount IS NULL OR p_total_amount <= 0 OR p_total_amount > 999999999999.99 OR p_total_amount <> round(p_total_amount, 2) THEN RAISE EXCEPTION 'total_amount is invalid' USING ERRCODE = '22023'; END IF; IF p_business_line_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.business_lines AS business_line WHERE business_line.id = p_business_line_id AND business_line.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Business line does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_cost_center_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.cost_centers AS cost_center WHERE cost_center.id = p_cost_center_id AND cost_center.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Cost center does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_accounting_account_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.accounting_accounts AS accounting_account WHERE accounting_account.id = p_accounting_account_id AND accounting_account.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Accounting account does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_document_type_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.document_types AS document_type WHERE document_type.id = p_document_type_id ) THEN RAISE EXCEPTION 'Document type does not exist' USING ERRCODE = '23503'; END IF; INSERT INTO tuasesor.expense_report_items ( expense_report_id, business_line_id, cost_center_id, accounting_account_id, expense_date, supplier_name, document_type_id, document_number, total_amount, description, additional_notes ) VALUES ( p_expense_report_id, p_business_line_id, p_cost_center_id, p_accounting_account_id, p_expense_date, nullif(btrim(p_supplier_name), ''), p_document_type_id, nullif(btrim(p_document_number), ''), p_total_amount, nullif(btrim(p_description), ''), nullif(btrim(p_additional_notes), '') ) RETURNING * INTO v_item; RETURN v_item; END; $$
  • "delete_expense_report_item"("p_workspace_id" "uuid", "p_expense_report_id" "uuid", "p_item_id" "uuid") RETURNS "uuid" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ DECLARE v_report tuasesor.expense_reports; v_deleted_item_id uuid; BEGIN IF auth.uid() IS NULL THEN RAISE EXCEPTION 'Authentication is required' USING ERRCODE = '42501'; END IF; IF p_workspace_id IS NULL OR p_expense_report_id IS NULL OR p_item_id IS NULL THEN RAISE EXCEPTION 'Workspace, expense report and item are required' USING ERRCODE = '22023'; END IF; SELECT expense_report.* INTO v_report FROM tuasesor.expense_reports AS expense_report WHERE expense_report.id = p_expense_report_id AND expense_report.workspace_id = p_workspace_id; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report was not found' USING ERRCODE = 'P0002'; END IF; IF NOT tuasesor.can_write_workspace(p_workspace_id) THEN RAISE EXCEPTION 'Not authorized to write in this workspace' USING ERRCODE = '42501'; END IF; IF v_report.status <> 'draft' THEN RAISE EXCEPTION 'Expense report is not editable' USING ERRCODE = '55000'; END IF; DELETE FROM tuasesor.expense_report_items WHERE id = p_item_id AND expense_report_id = p_expense_report_id RETURNING id INTO v_deleted_item_id; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report item was not found' USING ERRCODE = 'P0002'; END IF; RETURN v_deleted_item_id; END; $$
  • "handle_auth_user_created"() RETURNS "trigger" LANGUAGE "plpgsql" SECURITY DEFINER SET "search_path" TO 'public' AS $$ DECLARE resolved_full_name text; resolved_avatar_url text; resolved_auth_metadata jsonb; BEGIN IF new.email IS NULL OR btrim(new.email) = '' THEN RAISE EXCEPTION 'Cannot synchronize auth user % without an email address', new.id; END IF; resolved_full_name := coalesce( nullif(new.raw_user_meta_data ->> 'full_name', ''), nullif(new.raw_user_meta_data ->> 'name', '') ); resolved_avatar_url := coalesce( nullif(new.raw_user_meta_data ->> 'avatar_url', ''), nullif(new.raw_user_meta_data ->> 'picture', '') ); resolved_auth_metadata := jsonb_build_object( 'auth', jsonb_build_object( 'provider', new.raw_app_meta_data ->> 'provider', 'providers', coalesce( new.raw_app_meta_data -> 'providers', '[]'::jsonb ), 'provider_id', new.raw_user_meta_data ->> 'provider_id', 'email_verified', coalesce( (new.raw_user_meta_data ->> 'email_verified')::boolean, false ) ) ); INSERT INTO tuasesor.profiles ( id, email, full_name, avatar_url, metadata_json ) VALUES ( new.id, new.email, resolved_full_name, resolved_avatar_url, resolved_auth_metadata ) ON CONFLICT (id) DO UPDATE SET email = excluded.email, full_name = coalesce( excluded.full_name, tuasesor.profiles.full_name ), avatar_url = coalesce( excluded.avatar_url, tuasesor.profiles.avatar_url ), metadata_json = coalesce(tuasesor.profiles.metadata_json, '{}'::jsonb) \|\| excluded.metadata_json, updated_at = now(); RETURN new; END; $$
  • "prevent_expense_report_item_parent_change"() RETURNS "trigger" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ BEGIN IF NEW.expense_report_id IS DISTINCT FROM OLD.expense_report_id THEN RAISE EXCEPTION 'expense_report_id cannot be changed' USING ERRCODE = '22023'; END IF; RETURN NEW; END; $$
  • "update_expense_report_item"("p_workspace_id" "uuid", "p_expense_report_id" "uuid", "p_item_id" "uuid", "p_expense_date" "date", "p_total_amount" numeric, "p_supplier_name" "text", "p_document_type_id" integer, "p_document_number" "text", "p_description" "text", "p_business_line_id" "uuid", "p_cost_center_id" "uuid", "p_accounting_account_id" "uuid", "p_additional_notes" "text") RETURNS "tuasesor"."expense_report_items" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ DECLARE v_report tuasesor.expense_reports; v_item tuasesor.expense_report_items; BEGIN IF auth.uid() IS NULL THEN RAISE EXCEPTION 'Authentication is required' USING ERRCODE = '42501'; END IF; IF p_workspace_id IS NULL OR p_expense_report_id IS NULL OR p_item_id IS NULL THEN RAISE EXCEPTION 'Workspace, expense report and item are required' USING ERRCODE = '22023'; END IF; SELECT expense_report.* INTO v_report FROM tuasesor.expense_reports AS expense_report WHERE expense_report.id = p_expense_report_id AND expense_report.workspace_id = p_workspace_id; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report was not found' USING ERRCODE = 'P0002'; END IF; IF NOT tuasesor.can_write_workspace(p_workspace_id) THEN RAISE EXCEPTION 'Not authorized to write in this workspace' USING ERRCODE = '42501'; END IF; IF v_report.status <> 'draft' THEN RAISE EXCEPTION 'Expense report is not editable' USING ERRCODE = '55000'; END IF; IF p_expense_date IS NULL THEN RAISE EXCEPTION 'expense_date is required' USING ERRCODE = '22023'; END IF; IF p_total_amount IS NULL OR p_total_amount <= 0 OR p_total_amount > 999999999999.99 OR p_total_amount <> round(p_total_amount, 2) THEN RAISE EXCEPTION 'total_amount is invalid' USING ERRCODE = '22023'; END IF; IF p_business_line_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.business_lines AS business_line WHERE business_line.id = p_business_line_id AND business_line.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Business line does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_cost_center_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.cost_centers AS cost_center WHERE cost_center.id = p_cost_center_id AND cost_center.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Cost center does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_accounting_account_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.accounting_accounts AS accounting_account WHERE accounting_account.id = p_accounting_account_id AND accounting_account.workspace_id = p_workspace_id ) THEN RAISE EXCEPTION 'Accounting account does not belong to the workspace' USING ERRCODE = '23503'; END IF; IF p_document_type_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.document_types AS document_type WHERE document_type.id = p_document_type_id ) THEN RAISE EXCEPTION 'Document type does not exist' USING ERRCODE = '23503'; END IF; UPDATE tuasesor.expense_report_items SET business_line_id = p_business_line_id, cost_center_id = p_cost_center_id, accounting_account_id = p_accounting_account_id, expense_date = p_expense_date, supplier_name = nullif(btrim(p_supplier_name), ''), document_type_id = p_document_type_id, document_number = nullif(btrim(p_document_number), ''), total_amount = p_total_amount, description = nullif(btrim(p_description), ''), additional_notes = nullif(btrim(p_additional_notes), '') WHERE id = p_item_id AND expense_report_id = p_expense_report_id RETURNING * INTO v_item; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report item was not found' USING ERRCODE = 'P0002'; END IF; RETURN v_item; END; $$
  • "validate_expense_report_item_catalogs"() RETURNS "trigger" LANGUAGE "plpgsql" SET "search_path" TO 'pg_catalog', 'tuasesor' AS $$ DECLARE v_workspace_id uuid; BEGIN SELECT expense_report.workspace_id INTO v_workspace_id FROM tuasesor.expense_reports AS expense_report WHERE expense_report.id = NEW.expense_report_id; IF NOT FOUND THEN RAISE EXCEPTION 'Expense report was not found' USING ERRCODE = '23503'; END IF; IF NEW.business_line_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.business_lines AS business_line WHERE business_line.id = NEW.business_line_id AND business_line.workspace_id = v_workspace_id ) THEN RAISE EXCEPTION 'Business line does not belong to the expense report workspace' USING ERRCODE = '23503'; END IF; IF NEW.cost_center_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.cost_centers AS cost_center WHERE cost_center.id = NEW.cost_center_id AND cost_center.workspace_id = v_workspace_id ) THEN RAISE EXCEPTION 'Cost center does not belong to the expense report workspace' USING ERRCODE = '23503'; END IF; IF NEW.accounting_account_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.accounting_accounts AS accounting_account WHERE accounting_account.id = NEW.accounting_account_id AND accounting_account.workspace_id = v_workspace_id ) THEN RAISE EXCEPTION 'Accounting account does not belong to the expense report workspace' USING ERRCODE = '23503'; END IF; IF NEW.document_type_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM tuasesor.document_types AS document_type WHERE document_type.id = NEW.document_type_id ) THEN RAISE EXCEPTION 'Document type does not exist' USING ERRCODE = '23503'; END IF; RETURN NEW; END; $$

Schema grants

  • USAGE ON SCHEMA "tuasesor" TO "anon"
  • USAGE ON SCHEMA "tuasesor" TO "authenticated"
  • USAGE ON SCHEMA "tuasesor" TO "service_role"