Skip to content

Team member management, last login, build trigger and report theme toggle - #140

Merged
snevesbarros merged 1 commit into
masterfrom
ccr-2db5932d-yi60a6
Oct 16, 2026
Merged

snevesbarros merged 1 commit into
masterfrom
ccr-2db5932d-yi60a6

Conversation

@snevesbarros

Copy link
Copy Markdown
Collaborator

Summary

Back-end for four related features. UI, JS client and docs PRs are linked below.

  • Team members managed by team leads: GET/POST /team/:teamId/members and DELETE /team/:teamId/members/:userId. Allowed for admins and the team's own leads. Session-only, API tokens get 403, like the user routes.
    • A team lead can only add or remove users with the user role. They cannot add or remove other team leads or admins, and cannot remove themselves. team_lead membership is what grants lead powers, so otherwise a lead could hand out lead access to a team. Admins can manage anyone.
    • Members are added by username. Team leads cannot list all users, which would expose the user directory.
    • Responses contain only _id, username, role and authProvider.
    • User.teams is now indexed, because the member list is a lookup from the user side.
  • Last login: User.lastLoginAt is set on every successful sign-in (local, LDAP, SSO callback) through one completeLogin helper. updatedAt is not touched. A failure to record it is logged and never blocks the login. It is returned by the existing admin GET /users. API-token requests don't count as a login.
  • Who triggered a build: Build.triggeredBy { user, username, tokenName } is set in POST /build from the authenticated caller. tokenName is the API key's name (never the token). The username is copied so history survives account deletion. Builds created before this have no value.
  • HTML report theme toggle: a light/dark button in the report header. The theme is driven by data-theme. Until the viewer chooses, it follows the OS (the media query is guarded on the attribute being absent, as in the UI). The choice is remembered in localStorage and applied before first paint (the head script carries the report nonce, so the CSP is unchanged). The report prints in light mode. The toggle is hidden when JS is off. The report also gets a "Triggered by" fact.
  • Swagger updated for the new endpoints and fields.

Testing

  • New test/team-members.tests.js (32 tests): permissions and role rules, 403/404/409/422 paths, API-token rejection, last login (set, not set on failure, updatedAt unchanged, visible to admins), triggeredBy via session and API key (including after account deletion), report content.
  • Full suite: 667 passing against a local MongoDB.
  • The report toggle was exercised in Chromium: OS light and dark, override, persistence across reload.

Notes

  • eslint . still reports pre-existing errors in scripts/ and setup/, none in changed files.
  • Companion PRs: AnglesHQ/angles-ui, AnglesHQ/angles-javascript-client, AnglesHQ/angleshq.github.io.

🤖 Generated with Claude Code

https://claude.ai/code/session_0121r5gnmvth6hy4tPpNT8sM


Generated by Claude Code

…eme toggle

- Team leads (and admins) can list, add and remove the members of a team via
  GET/POST /team/:teamId/members and DELETE /team/:teamId/members/:userId.
  Session-only (API tokens are rejected). Team leads manage plain users only: they
  cannot add or remove other team leads or admins, nor remove themselves, so lead
  access cannot be handed out through membership.
- Record User.lastLoginAt on every successful sign-in (local, LDAP, SSO) without
  touching updatedAt; it is returned by the admin user endpoints.
- Record Build.triggeredBy (user, username snapshot and, for API-key requests, the
  token name) when a build is created.
- The HTML build report gets a light/dark toggle (data-theme, remembered in
  localStorage, OS preference until chosen, light when printing) and a
  "Triggered by" fact.
- Index User.teams; document the new endpoints and fields in swagger.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0121r5gnmvth6hy4tPpNT8sM
@snevesbarros
snevesbarros merged commit 10cccd9 into master Oct 16, 2026
1 check passed
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.

2 participants