Skip to content

fix: 일반 경로에 남은 VM 자국 정리 - #42

Merged
yessjun merged 8 commits into
mainfrom
fix/generic-request-surface
Aug 10, 2026
Merged

fix: 일반 경로에 남은 VM 자국 정리#42
yessjun merged 8 commits into
mainfrom
fix/generic-request-surface

Conversation

@yessjun

@yessjun yessjun commented Aug 10, 2026

Copy link
Copy Markdown
Member

📝 작업내용

  • 접근 권한 없는 행이 SSH 슬러그를 넘기던 것을 막았다, 이름 자리에 표시명이 들어가고 표시명이 없으면 식별용 이름으로 대체한다
  • 비회원 신청 거절이 승급을 요구하고 있었다, 실제 해법은 워크스페이스에 합류하는 것이라 문구와 코드를 구성원 기준으로 바꿨다
  • 신청 접수·승인·반려 알림이 종류를 따라 말한다, 종전에는 일반 경로에서 발화하면서 VM이라고 적었고 리소스 이름을 호스트명 키로 넘겼다
  • 알림 수신자 규칙을 종류 일반으로, 워크스페이스 삭제가 모든 종류를 세도록
  • 승인과 워크스페이스 삭제가 겹칠 때 죽은 워크스페이스에 살아 있는 리소스가 남던 창을 닫았다
  • 리소스 인벤토리 조회에 기능 테스트 신설, 종전에는 권한 매트릭스 행만 있고 그 행을 검증하는 것이 없었다

⭐️ 검증

  • api verify.sh 통과
  • 알림 합성은 발행 시점에 일어나 결과가 저장되므로 기존 알림 행은 영향받지 않는다
  • 계약 생성본은 병합 후 재생성해 현재 버전과 정합

💬 리뷰 포인트

  • 제한 행은 표시명을 이름 자리에 넣고 표시명 필드는 비운다, 둘 다 채우면 같은 이름이 두 번 나온다
  • 계약 버전은 건드리지 않았다, 이 변경은 스키마가 아니라 서술과 동작이다

A restricted row nulled hostname but passed vm.getName(), and approval
builds the VM with name == hostname, so the slug went out anyway. The
row now carries the display name, falling back to the id when the VM
has none; the name is never null because the console labels a row as
displayName || name.
The rule this 403 described was deleted: any member may ask, so the
throw now fires only for someone outside the workspace. It said the
caller lacked a rung and named VMs on a path every resource type
travels. New code WORKSPACE_MEMBERSHIP_REQUIRED.
The submitted/approved/rejected notices are fired from the generic
request and approval paths but were written as VM prose, and approval
passed the resource name under a key called hostname. The type already
travels in the args; the word now comes from it. VM's rendered text is
unchanged.
vmRecipients was typed on Vm and hardcoded ResourceType.VM, so a second
type would have needed a copy of a rule that does not depend on the
type. The VM helpers now pass their own type through.
Deletion counted VMs directly, so a workspace holding live resources of
a later type would have deleted cleanly. Each type answers through its
adapter, the way grant revocation already asks.

The count also moved after the in-flight requests are locked: taken
first it reads zero while an approval holds those locks uncommitted,
and the workspace is then soft-deleted around the VM that approval
creates.
A request submitted concurrently with a workspace delete commits after
that delete's cancellation sweep has run, so it survives as SUBMITTED.
Approving it is refused; rejecting it still works.
Nothing under src/test touched /api/v1/resources, so its permission
row was decorative. Covers a member's own workspace rows, an empty page
for a workspace filter outside the caller's memberships, the restricted
row (asserted against the whole body: the slug appears nowhere) and the
401.
@yessjun
yessjun merged commit 2bad96b into main Aug 10, 2026
1 check passed
@yessjun
yessjun deleted the fix/generic-request-surface branch August 10, 2026 09:41
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