mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
5a8d0016a5
> Mux updated this PR on behalf of Mike. ## Stack Context This PR is the storage, permissions, API, and SDK layer for experimental personal skills. #25362 has landed on `main`, so this branch is restacked directly on `main`. Stack order: 1. #25363 storage, permissions, API, and SDK 2. #25365 API test coverage 3. #25366 chattool and chatd integration 4. #25066 settings UI and docs 5. #25386 personal skills slash menu ## What? Adds the `user_skills` database table, generated queries, RBAC resources and scopes, audit resource handling, experimental user-scoped CRUD endpoints, SDK types, and generated API/site types. Follow-up review and restack fixes: - Enforce a bounded personal skill description in parser and database constraints. - Return `403 Forbidden` for unauthorized create and update attempts. - Return explicit conflict responses when soft-deleted users are targeted. - Keep user admins out of personal skills, while site owners can read and delete but not create or update. - Document trigger-raised constraint names and keep schema constants covered by tests. - Reuse `UserSkillMetadata` in the full `UserSkill` SDK response type. - Generate user skill IDs in Go instead of relying on a database default. - Rebase on latest `main` and renumber the user skills migration to `000502_user_skills`. ## Why? Personal skills need durable user-owned storage with owner authorization, limited site-owner moderation, and a hidden API surface before chatd can consume them. ## Validation - `make gen` - `go test ./coderd/database -run '^TestUserSkillSchemaConstants$' -count=1` - `go test ./coderd/database/dbauthz -run '^TestMethodTestSuite/TestUserSkills$' -count=1` - `go test ./coderd -run '^TestPatchUserSkill$' -count=1` - `go test ./codersdk ./coderd/database/db2sdk` - `make lint` - pre-commit hook on `97fd58108d`
44 lines
1.6 KiB
PL/PgSQL
44 lines
1.6 KiB
PL/PgSQL
-- Enum additions to resource_type and api_key_scope are intentionally not
|
|
-- reverted because Postgres cannot drop enum values safely.
|
|
DROP TRIGGER IF EXISTS trigger_upsert_user_skills ON user_skills;
|
|
DROP FUNCTION IF EXISTS insert_user_skill_fail_if_user_deleted;
|
|
|
|
-- Restore the previous body of delete_deleted_user_resources() from
|
|
-- migration 000492 (without the user_skills cleanup).
|
|
CREATE OR REPLACE FUNCTION delete_deleted_user_resources() RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
DECLARE
|
|
BEGIN
|
|
IF (NEW.deleted) THEN
|
|
-- Remove their api_keys.
|
|
DELETE FROM api_keys
|
|
WHERE user_id = OLD.id;
|
|
|
|
-- Remove their user_links.
|
|
-- Their login_type is preserved in the users table.
|
|
-- Matching this user back to the link can still be done by their
|
|
-- email if the account is undeleted. Although that is not a guarantee.
|
|
DELETE FROM user_links
|
|
WHERE user_id = OLD.id;
|
|
|
|
-- Remove their user_secrets.
|
|
-- user_secrets.user_id has ON DELETE CASCADE, but soft-delete
|
|
-- does not remove the users row so the FK cascade never fires.
|
|
DELETE FROM user_secrets
|
|
WHERE user_id = OLD.id;
|
|
|
|
-- Remove their organization memberships.
|
|
-- This also triggers group membership cleanup via
|
|
-- trigger_delete_group_members_on_org_member_delete.
|
|
DELETE FROM organization_members
|
|
WHERE user_id = OLD.id;
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
DROP TRIGGER IF EXISTS trigger_user_skills_per_user_limit ON user_skills;
|
|
DROP FUNCTION IF EXISTS enforce_user_skills_per_user_limit();
|
|
DROP TABLE user_skills;
|