feat: profiles and /set profile, and id cards
* New functionality to set meta data on businesscards. * Can develop a user profile. * Business cards link to user profile.
This commit is contained in:
parent
cd8dfb94a3
commit
710985638f
35 changed files with 4932 additions and 435 deletions
|
|
@ -16,6 +16,7 @@ CREATE TABLE auth.users (
|
|||
|
||||
username auth.username NOT NULL,
|
||||
email auth.email,
|
||||
phone TEXT, -- TODO: migrate to auth.phone_number domain
|
||||
password_hash TEXT,
|
||||
auth_provider auth.auth_provider NOT NULL DEFAULT 'local',
|
||||
oauth_id TEXT,
|
||||
|
|
@ -24,6 +25,16 @@ CREATE TABLE auth.users (
|
|||
bio TEXT,
|
||||
avatar_url public.url,
|
||||
|
||||
-- HOSS membership profile fields
|
||||
name_first TEXT,
|
||||
name_last TEXT,
|
||||
summary TEXT, -- Brief one-liner tagline
|
||||
homepage public.url,
|
||||
avatar_source auth.avatar_source NOT NULL DEFAULT 'local',
|
||||
profile_visibility auth.profile_visibility NOT NULL DEFAULT 'public',
|
||||
contacts_visibility auth.profile_visibility NOT NULL DEFAULT 'members',
|
||||
organizations_visibility auth.profile_visibility NOT NULL DEFAULT 'members',
|
||||
|
||||
-- User preferences for default avatar selection
|
||||
birthday DATE,
|
||||
gender_preference auth.gender_preference NOT NULL DEFAULT 'gender_neutral',
|
||||
|
|
@ -127,6 +138,71 @@ CREATE INDEX idx_auth_friendships_friend_a ON auth.friendships (friend_a);
|
|||
CREATE INDEX idx_auth_friendships_friend_b ON auth.friendships (friend_b);
|
||||
CREATE INDEX idx_auth_friendships_pending ON auth.friendships (is_accepted) WHERE is_accepted = false;
|
||||
|
||||
-- =============================================================================
|
||||
-- User Contacts (Social/Contact Links)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE auth.user_contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
platform auth.contact_platform NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
label TEXT, -- Optional display label
|
||||
sort_order SMALLINT NOT NULL DEFAULT 0,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
|
||||
CONSTRAINT uq_auth_user_contacts_platform UNIQUE (user_id, platform, value),
|
||||
CONSTRAINT chk_auth_user_contacts_value_nonempty CHECK (length(trim(value)) > 0)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE auth.user_contacts IS 'User social/contact platform links';
|
||||
COMMENT ON COLUMN auth.user_contacts.platform IS 'Type of contact (discord, github, linkedin, etc.)';
|
||||
COMMENT ON COLUMN auth.user_contacts.value IS 'Platform-specific identifier (handle, URL, phone, etc.)';
|
||||
COMMENT ON COLUMN auth.user_contacts.label IS 'Optional user-friendly display label';
|
||||
COMMENT ON COLUMN auth.user_contacts.sort_order IS 'Display order (lower = first)';
|
||||
|
||||
CREATE INDEX idx_auth_user_contacts_user ON auth.user_contacts (user_id);
|
||||
CREATE INDEX idx_auth_user_contacts_platform ON auth.user_contacts (platform);
|
||||
|
||||
-- =============================================================================
|
||||
-- User Organizations (Affiliations)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE auth.user_organizations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
wikidata_qid public.wikidata_qid, -- Wikidata Q-number for org
|
||||
name TEXT NOT NULL, -- Display name (may differ from Wikidata)
|
||||
role TEXT, -- User's role/title
|
||||
department TEXT, -- Department/division
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
is_current BOOLEAN NOT NULL DEFAULT true,
|
||||
sort_order SMALLINT NOT NULL DEFAULT 0,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
|
||||
CONSTRAINT chk_auth_user_orgs_name_nonempty CHECK (length(trim(name)) > 0),
|
||||
CONSTRAINT chk_auth_user_orgs_dates CHECK (start_date IS NULL OR end_date IS NULL OR start_date <= end_date)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE auth.user_organizations IS 'User organizational affiliations';
|
||||
COMMENT ON COLUMN auth.user_organizations.wikidata_qid IS 'Wikidata Q-number for standardized organization lookup';
|
||||
COMMENT ON COLUMN auth.user_organizations.name IS 'Display name for the organization';
|
||||
COMMENT ON COLUMN auth.user_organizations.role IS 'User role/title at the organization';
|
||||
COMMENT ON COLUMN auth.user_organizations.is_current IS 'Whether this is a current affiliation';
|
||||
|
||||
CREATE INDEX idx_auth_user_organizations_user ON auth.user_organizations (user_id);
|
||||
CREATE INDEX idx_auth_user_organizations_wikidata ON auth.user_organizations (wikidata_qid)
|
||||
WHERE wikidata_qid IS NOT NULL;
|
||||
CREATE INDEX idx_auth_user_organizations_current ON auth.user_organizations (user_id, is_current)
|
||||
WHERE is_current = true;
|
||||
|
||||
-- =============================================================================
|
||||
-- Block List
|
||||
-- =============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue