Files
member-platform/docs/DB_SCHEMA_SNAPSHOT.md

8.4 KiB

DB Schema Snapshot

  • Date: 2026-03-30
  • Database: member.ose.tw
  • Schema: public

Tables

  • api_clients
  • auth_sync_state
  • companies
  • modules
  • permissions
  • sites
  • user_scope_permissions
  • users

api_clients

Columns

  • id: uuid (not null: true)
  • client_key: text (not null: true)
  • name: text (not null: true)
  • status: client_status (not null: true)
  • api_key_hash: text (not null: true)
  • allowed_origins: jsonb (not null: true)
  • allowed_ips: jsonb (not null: true)
  • allowed_paths: jsonb (not null: true)
  • rate_limit_per_min: integer (not null: false)
  • expires_at: timestamp with time zone (not null: false)
  • last_used_at: timestamp with time zone (not null: false)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • api_clients_client_key_key (u): UNIQUE (client_key)
  • api_clients_pkey (p): PRIMARY KEY (id)

Indexes

  • api_clients_client_key_key: CREATE UNIQUE INDEX api_clients_client_key_key ON public.api_clients USING btree (client_key)
  • api_clients_pkey: CREATE UNIQUE INDEX api_clients_pkey ON public.api_clients USING btree (id)
  • idx_api_clients_expires_at: CREATE INDEX idx_api_clients_expires_at ON public.api_clients USING btree (expires_at)
  • idx_api_clients_status: CREATE INDEX idx_api_clients_status ON public.api_clients USING btree (status)

auth_sync_state

Columns

  • user_id: uuid (not null: true)
  • last_synced_at: timestamp with time zone (not null: false)
  • source_version: text (not null: false)
  • last_error: text (not null: false)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • auth_sync_state_pkey (p): PRIMARY KEY (user_id)
  • auth_sync_state_user_id_fkey (f): FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE

Indexes

  • auth_sync_state_pkey: CREATE UNIQUE INDEX auth_sync_state_pkey ON public.auth_sync_state USING btree (user_id)

companies

Columns

  • id: uuid (not null: true)
  • company_key: text (not null: true)
  • name: text (not null: true)
  • status: record_status (not null: true)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • companies_company_key_key (u): UNIQUE (company_key)
  • companies_pkey (p): PRIMARY KEY (id)

Indexes

  • companies_company_key_key: CREATE UNIQUE INDEX companies_company_key_key ON public.companies USING btree (company_key)
  • companies_pkey: CREATE UNIQUE INDEX companies_pkey ON public.companies USING btree (id)

modules

Columns

  • id: uuid (not null: true)
  • module_key: text (not null: true)
  • name: text (not null: true)
  • status: record_status (not null: true)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • modules_module_key_key (u): UNIQUE (module_key)
  • modules_pkey (p): PRIMARY KEY (id)

Indexes

  • modules_module_key_key: CREATE UNIQUE INDEX modules_module_key_key ON public.modules USING btree (module_key)
  • modules_pkey: CREATE UNIQUE INDEX modules_pkey ON public.modules USING btree (id)

permissions

Columns

  • id: uuid (not null: true)
  • user_id: uuid (not null: true)
  • scope_type: character varying(32) (not null: true)
  • scope_id: character varying(128) (not null: true)
  • module: character varying(128) (not null: true)
  • action: character varying(32) (not null: true)
  • created_at: timestamp with time zone (not null: true)

Constraints

  • permissions_pkey (p): PRIMARY KEY (id)
  • permissions_user_id_fkey (f): FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
  • uq_permissions_user_scope_module_action (u): UNIQUE (user_id, scope_type, scope_id, module, action)

Indexes

  • idx_permissions_user_id: CREATE INDEX idx_permissions_user_id ON public.permissions USING btree (user_id)
  • permissions_pkey: CREATE UNIQUE INDEX permissions_pkey ON public.permissions USING btree (id)
  • uq_permissions_user_scope_module_action: CREATE UNIQUE INDEX uq_permissions_user_scope_module_action ON public.permissions USING btree (user_id, scope_type, scope_id, module, action)

sites

Columns

  • id: uuid (not null: true)
  • site_key: text (not null: true)
  • company_id: uuid (not null: true)
  • name: text (not null: true)
  • status: record_status (not null: true)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • sites_company_id_fkey (f): FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
  • sites_pkey (p): PRIMARY KEY (id)
  • sites_site_key_key (u): UNIQUE (site_key)

Indexes

  • idx_sites_company_id: CREATE INDEX idx_sites_company_id ON public.sites USING btree (company_id)
  • sites_pkey: CREATE UNIQUE INDEX sites_pkey ON public.sites USING btree (id)
  • sites_site_key_key: CREATE UNIQUE INDEX sites_site_key_key ON public.sites USING btree (site_key)

user_scope_permissions

Columns

  • id: uuid (not null: true)
  • user_id: uuid (not null: true)
  • module_id: uuid (not null: true)
  • action: permission_action (not null: true)
  • scope_type: scope_type (not null: true)
  • company_id: uuid (not null: false)
  • site_id: uuid (not null: false)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)

Constraints

  • user_scope_permissions_check (c): CHECK ((((scope_type = 'company'::scope_type) AND (company_id IS NOT NULL) AND (site_id IS NULL)) OR ((scope_type = 'site'::scope_type) AND (site_id IS NOT NULL) AND (company_id IS NULL))))
  • user_scope_permissions_company_id_fkey (f): FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE
  • user_scope_permissions_module_id_fkey (f): FOREIGN KEY (module_id) REFERENCES modules(id) ON DELETE CASCADE
  • user_scope_permissions_pkey (p): PRIMARY KEY (id)
  • user_scope_permissions_site_id_fkey (f): FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
  • user_scope_permissions_user_id_fkey (f): FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE

Indexes

  • idx_usp_company_id: CREATE INDEX idx_usp_company_id ON public.user_scope_permissions USING btree (company_id)
  • idx_usp_module_id: CREATE INDEX idx_usp_module_id ON public.user_scope_permissions USING btree (module_id)
  • idx_usp_site_id: CREATE INDEX idx_usp_site_id ON public.user_scope_permissions USING btree (site_id)
  • idx_usp_user_id: CREATE INDEX idx_usp_user_id ON public.user_scope_permissions USING btree (user_id)
  • uq_usp_company: CREATE UNIQUE INDEX uq_usp_company ON public.user_scope_permissions USING btree (user_id, module_id, action, scope_type, company_id) WHERE (scope_type = 'company'::scope_type)
  • uq_usp_site: CREATE UNIQUE INDEX uq_usp_site ON public.user_scope_permissions USING btree (user_id, module_id, action, scope_type, site_id) WHERE (scope_type = 'site'::scope_type)
  • user_scope_permissions_pkey: CREATE UNIQUE INDEX user_scope_permissions_pkey ON public.user_scope_permissions USING btree (id)

users

Columns

  • id: uuid (not null: true)
  • authentik_sub: text (not null: true)
  • email: text (not null: false)
  • display_name: text (not null: false)
  • status: record_status (not null: true)
  • created_at: timestamp with time zone (not null: true)
  • updated_at: timestamp with time zone (not null: true)
  • authentik_user_id: integer (not null: false)
  • is_active: boolean (not null: true)

Constraints

  • users_authentik_sub_key (u): UNIQUE (authentik_sub)
  • users_email_key (u): UNIQUE (email)
  • users_pkey (p): PRIMARY KEY (id)

Indexes

  • idx_users_authentik_sub: CREATE INDEX idx_users_authentik_sub ON public.users USING btree (authentik_sub)
  • users_authentik_sub_key: CREATE UNIQUE INDEX users_authentik_sub_key ON public.users USING btree (authentik_sub)
  • users_email_key: CREATE UNIQUE INDEX users_email_key ON public.users USING btree (email)
  • users_pkey: CREATE UNIQUE INDEX users_pkey ON public.users USING btree (id)