You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Went through the Copilot file-summary finding that had no review thread. It was valid:
apps/admin/src/app/components/EntitlementList.tsx: fixed. Heroicons always render aria-hidden="true", so the aria-labels on the icons were never announced. The enabled/disabled state is now visually hidden text next to each label.
Went through Copilot's file-summary notes that didn't become review threads — one was valid:
apps/admin/src/app/components/EntitlementList.tsx — fixed, enabled/disabled is now announced via visually hidden text instead of icon color only (d372b6d).
…okup
Adds apps/admin-api (Express), apps/admin (React + Tailwind) and libs/admin/types.
- Google OAuth sign-in restricted to the Workspace domain plus an email allowlist,
encrypted session cookie, CSRF header check and optional Cloudflare Access JWT check
- Provision a team linked to an existing Stripe customer/quote, re-apply the Stripe link,
and send/resend/revoke invitations (emails only go out on an explicit admin action)
- Search and view teams and users, dashboard KPI tiles
- New ADMIN_* audit log actions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012fHLkLy4QS7pgaQqqnpVnM
…seat-mode wording
- Paginate users and teams; filter users by plan (team/professional/free) and sort by last login or created
- Plan status counts active team membership, not only personal subscriptions
- Approve a team domain (marks it verified and updates the login configuration)
- Add existing users to a team without an invitation, during provisioning or from the team page
- Rename billing mode to seat mode (follow subscription / fixed by agreement) with accurate descriptions
- Generic login page, admin favicon, SQL script to seed fake users locally
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012fHLkLy4QS7pgaQqqnpVnM
Team and user billing cards read the customer straight from Stripe and let an
admin set or clear metadata.productionOrgId, which Checkout only collects from
buyers who go through it. Also flags a seat limit that Stripe has not synced
yet and says plainly that re-linking only triggers the webhook.
The session cookie is a bearer token. When Access is in front, a cookie now only
works from the Access session of the admin it was issued to, and sign-in refuses
a Google account that differs from the Access identity.
…notes digest
The admin app is staff-only. The context script sets admin PRs and `(admin)`
commits aside under "Excluded", and the commit and release-notes guides say to
use the `admin` scope and PR label, which `.github/release.yml` already excludes
from GitHub Release notes.
…omain
Every writer rebuilds LoginConfiguration.domains from the team's verified
records, so two concurrent changes on one team could each miss the other's
uncommitted record and the later write silently removed a domain from SSO and
domain auto-join. The main API's verify/delete paths and the admin approval
now lock the login configuration row before reading the records.
Stripe's entitlement summary event only fires when entitlements change, so a
customer whose subscription started before it was linked to a team (as admin
provisioning does) never synced and the team kept all-false entitlements until
someone opened its billing page. Writes the team's entitlements directly
rather than through fetchAndUpdateEntitlements, which branches on customer
metadata that can still read USER while a team is being auto-created.
…'s URL
useApiQuery kept the previous path's data across a change of path and after a
failed fetch, so moving between two users or teams could leave the first
record's billing and member actions live under the second one's URL. Data from
another path is now dropped unless the caller opts in with keepPreviousData,
which only the list and search views and the provisioning wizard do.
Patching a member's live sessions with the new membership granted team access
without the team's login rules, and a new team requires MFA by default.
Revoking the sessions instead makes the next sign-in enforce them, the same
outcome the main API reaches by revoking sessions that violate the policy.
- Rate limit every request ahead of the Cloudflare Access check
- Page through all current subscriptions; status=all with a 20 item page
could hide an active Team plan behind older canceled ones
- Log rather than throw a failed audit write once the team has committed, so
the Stripe link still runs and the admin lands on the new team
…ent display
- A failed logout leaves the session cookie in place, so it now shows a
retryable error instead of navigating to the sign-in page
- Scale Stripe amounts by Stripe's zero and three decimal currency lists
- Announce entitlement state with visually hidden text, since heroicons are
always aria-hidden and ignored the aria-label
…action
Revocation ran after the membership committed and only logged a failure, so
a failed delete left pre-team sessions live without the team's MFA/SSO
rules, and a retry 409'd on the existing membership. Provisioning also
skipped it entirely when its audit write threw.
…starts
Subscription schedule events run the team sync before a future-start
subscription exists, and the entitlement pull then wiped the access granted
at provisioning. The pull now needs an active subscription; revoking access
when one ends is left to the entitlement summary event, which fires on every
change.
[P2] Keep post-commit audit failures from reporting successful mutations as failed. recordMembersAdded can reject after membership creation and session revocation commit, so the UI reports “User not added” and retrying hits the existing-membership conflict. The same problem occurs after domain approval in team-domains.service.ts:72–78 and after Stripe saves the production org id in stripe-customers.service.ts:79–96 (including the linked-account reads). Catch and explicitly log this post-mutation bookkeeping failure while returning the saved result, matching team-provisioning.service.ts:101–114 and 152–163. Add failure-path tests confirming that persisted changes still return success.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
adminInternal admin app (staff only); excluded from release notes
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.