Skip to content

feat(project-roles): create roles and grant or remove a role for a member (EP-08 #245) - #265

Open
ademboukabes wants to merge 7 commits into
MicroClub-USTHB:devfrom
ademboukabes:feat/ep-08-project-roles
Open

ademboukabes wants to merge 7 commits into
MicroClub-USTHB:devfrom
ademboukabes:feat/ep-08-project-roles

Conversation

@ademboukabes

Copy link
Copy Markdown
Collaborator

Closes #245

What and why

Implements the EP-08 Project API endpoints so the Event Platform can create event roles and grant or remove them for members automatically, under the manage_roles scope, with strict anti-escalation and hierarchy protection.

Endpoints added:

  • POST /api/servers/:serverId/roles: creates a Discord role with no permissions (permissions: 0n), derives hierarchy level, stores in roles, and records project ownership in project_created_roles.
  • PUT /api/servers/:serverId/members/:discordId/roles/:roleId: assigns role to member on Discord, records in server_member_roles, invalidates permission cache, returns 204 No Content (idempotent on repeat).
  • DELETE /api/servers/:serverId/members/:discordId/roles/:roleId: removes role on Discord, deletes from server_member_roles, invalidates permission cache, returns 204 No Content (idempotent on repeat).

Security controls:

  • Blocked with 403 Forbidden if the role was not created by the calling project.
  • Blocked with 403 Forbidden if the role is protected/root/executive (MC_EXECUTIVE_ROLE_ID, MC_DEV_LEADS_ROLE_ID, MC_IT_LEADS_ROLE_ID, or isGlobal).
  • Audit log entry recorded on unauthorized role manipulation (actionType: 'access', action: 'role_escalation_attempt', severity 'warning').
  • Blocked with 403 Forbidden if role position is equal to or higher than the bot's highest role.

Acceptance criteria

  • Given a role the project created, then it can be granted and removed, and a repeat is a no-op (204): project-roles.service.spec.ts, project-roles.e2e-spec.ts
  • Given an executive or any role the project did not create, then the answer is 403 and an audit entry exists: project-roles.service.spec.ts, project-roles.e2e-spec.ts
  • Given a role above the bot, then the answer is 403: project-roles.service.spec.ts
  • Created roles have no Discord permissions by default (permissions: 0n): project-roles.service.spec.ts, project-roles.e2e-spec.ts
  • The endpoint is documented, OpenAPI spec and generated CLI types are committed: apps/api/openapi.json, apps/web/src/content/docs/api-reference/project/roles.mdx, apps/cli/src/generated/api.d.ts

Checked

  • pnpm turbo run lint typecheck: 11/11 tasks clean across all packages
  • pnpm turbo run test: all unit and e2e test suites pass (116 suites / 1446 tests in api, 120 suites / 1404 tests in web, 47 suites / 311 tests in cli)
  • pnpm turbo run build: all packages build cleanly
  • OpenAPI spec exported via pnpm docs:api
  • CLI types regenerated via pnpm --filter mcid-cli generate:api-types
  • Drizzle migration 0012_pale_pretty_boy.sql verified idempotent (CREATE TABLE IF NOT EXISTS, guarded foreign keys in DO $$ ... $$)

Scope and limit

  • New project scope manage_roles added to @mcid/contracts and admin UI pickers (ScopeSelector, ServerAccessMatrix).
  • Projects can only manage roles that they have created themselves; cannot modify existing server roles or executive roles.
  • Role permissions are fixed at 0 bitfield upon creation; editing permissions or deleting roles is out of scope per EP-08 spec.

@ademboukabes
ademboukabes force-pushed the feat/ep-08-project-roles branch from e1571a5 to f6f1c10 Compare November 14, 2026 01:12

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant