mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat(coderd/database): track user status changes over time (#16019)
RE: https://github.com/coder/coder/issues/15740, https://github.com/coder/coder/issues/15297 In order to add a graph to the coder frontend to show user status over time as an indicator of license usage, this PR adds the following: * a new `api.insightsUserStatusCountsOverTime` endpoint to the API * which calls a new `GetUserStatusCountsOverTime` query from postgres * which relies on two new tables `user_status_changes` and `user_deleted` * which are populated by a new trigger and function that tracks updates to the users table The chart itself will be added in a subsequent PR --------- Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
This commit is contained in:
Generated
+65
@@ -423,6 +423,36 @@ $$;
|
||||
|
||||
COMMENT ON FUNCTION provisioner_tagset_contains(provisioner_tags tagset, job_tags tagset) IS 'Returns true if the provisioner_tags contains the job_tags, or if the job_tags represents an untagged provisioner and the superset is exactly equal to the subset.';
|
||||
|
||||
CREATE FUNCTION record_user_status_change() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF TG_OP = 'INSERT' OR OLD.status IS DISTINCT FROM NEW.status THEN
|
||||
INSERT INTO user_status_changes (
|
||||
user_id,
|
||||
new_status,
|
||||
changed_at
|
||||
) VALUES (
|
||||
NEW.id,
|
||||
NEW.status,
|
||||
NEW.updated_at
|
||||
);
|
||||
END IF;
|
||||
|
||||
IF OLD.deleted = FALSE AND NEW.deleted = TRUE THEN
|
||||
INSERT INTO user_deleted (
|
||||
user_id,
|
||||
deleted_at
|
||||
) VALUES (
|
||||
NEW.id,
|
||||
NEW.updated_at
|
||||
);
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION remove_organization_member_role() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
@@ -1377,6 +1407,14 @@ CREATE VIEW template_with_names AS
|
||||
|
||||
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
|
||||
CREATE TABLE user_deleted (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
user_id uuid NOT NULL,
|
||||
deleted_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE user_deleted IS 'Tracks when users were deleted';
|
||||
|
||||
CREATE TABLE user_links (
|
||||
user_id uuid NOT NULL,
|
||||
login_type login_type NOT NULL,
|
||||
@@ -1395,6 +1433,15 @@ COMMENT ON COLUMN user_links.oauth_refresh_token_key_id IS 'The ID of the key us
|
||||
|
||||
COMMENT ON COLUMN user_links.claims IS 'Claims from the IDP for the linked user. Includes both id_token and userinfo claims. ';
|
||||
|
||||
CREATE TABLE user_status_changes (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
user_id uuid NOT NULL,
|
||||
new_status user_status NOT NULL,
|
||||
changed_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE user_status_changes IS 'Tracks the history of user status changes';
|
||||
|
||||
CREATE TABLE workspace_agent_log_sources (
|
||||
workspace_agent_id uuid NOT NULL,
|
||||
id uuid NOT NULL,
|
||||
@@ -1980,9 +2027,15 @@ ALTER TABLE ONLY template_versions
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY user_deleted
|
||||
ADD CONSTRAINT user_deleted_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY user_links
|
||||
ADD CONSTRAINT user_links_pkey PRIMARY KEY (user_id, login_type);
|
||||
|
||||
ALTER TABLE ONLY user_status_changes
|
||||
ADD CONSTRAINT user_status_changes_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY users
|
||||
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -2093,6 +2146,10 @@ CREATE INDEX idx_tailnet_tunnels_dst_id ON tailnet_tunnels USING hash (dst_id);
|
||||
|
||||
CREATE INDEX idx_tailnet_tunnels_src_id ON tailnet_tunnels USING hash (src_id);
|
||||
|
||||
CREATE INDEX idx_user_deleted_deleted_at ON user_deleted USING btree (deleted_at);
|
||||
|
||||
CREATE INDEX idx_user_status_changes_changed_at ON user_status_changes USING btree (changed_at);
|
||||
|
||||
CREATE UNIQUE INDEX idx_users_email ON users USING btree (email) WHERE (deleted = false);
|
||||
|
||||
CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE (deleted = false);
|
||||
@@ -2235,6 +2292,8 @@ CREATE TRIGGER trigger_upsert_user_links BEFORE INSERT OR UPDATE ON user_links F
|
||||
|
||||
CREATE TRIGGER update_notification_message_dedupe_hash BEFORE INSERT OR UPDATE ON notification_messages FOR EACH ROW EXECUTE FUNCTION compute_notification_message_dedupe_hash();
|
||||
|
||||
CREATE TRIGGER user_status_change_trigger AFTER INSERT OR UPDATE ON users FOR EACH ROW EXECUTE FUNCTION record_user_status_change();
|
||||
|
||||
ALTER TABLE ONLY api_keys
|
||||
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
@@ -2358,6 +2417,9 @@ ALTER TABLE ONLY templates
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY user_deleted
|
||||
ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
|
||||
ALTER TABLE ONLY user_links
|
||||
ADD CONSTRAINT user_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
|
||||
@@ -2367,6 +2429,9 @@ ALTER TABLE ONLY user_links
|
||||
ALTER TABLE ONLY user_links
|
||||
ADD CONSTRAINT user_links_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY user_status_changes
|
||||
ADD CONSTRAINT user_status_changes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_log_sources
|
||||
ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user