목적
MVP2-0 Organization Membership / Invitation Foundation 작업의 최종 회귀 검증 게이트를 만든다.
핵심은 team_memberships에 의존하던 “조직 소속” 기준을 organization_memberships 전제 계층으로 바꾼 뒤에도 MVP1 workflow/LLM permission flow가 깨지지 않는지 확인하는 것이다. 신규 organization member/invitation flow는 API/UI 레벨에서 통과해야 하며, member removal 이후에는 workflow/LLM/direct/team 기반 접근이 즉시 차단되어야 한다.
문서 정합성
기준 문서: docs/implementation-plan/mvp-2-0-organization-membership-plan.md
이 이슈는 문서의 다음 항목과 직접 대응한다.
Issue 0-6. [Test][QA] MVP2-0 regression
- migration test
- permission helper unit test
- organization member API test
- team membership API regression
- user direct permission regression
- MVP1 demo smoke 재검증
19. 테스트 상세
- 19.1 Migration test
- 19.2 Permission helper test
- 19.3 API test
- 19.4 Team API regression
- 19.5 MVP2 knowledge permission 준비 test
22. 완료 기준
- DB, Organization context, Invitation, Acceptance, Team, User direct permission, Enforcement, Cleanup, Audit, UI, Regression
23. Demo script
- invite -> pending access blocked -> accept -> direct builder grant without team -> access allowed -> team permission -> remove -> access blocked
24. 리스크와 대응
- migration backfill 누락
- membership/team mismatch
- direct permission 잔존
- last manager 제거
- invited user 접근 허용
- MVP1 regression
이 이슈는 신규 제품 기능을 추가하는 이슈가 아니라, 0-1~0-5 구현 결과를 검증하고 문서 acceptance를 만족하는지 확인하는 회귀/QA 이슈다.
선행 조건 / 의존성
- Blocked by:
MBA-54 Issue 0-5 FE Members UI
- Transitive dependency:
MBA-51 Issue 0-1 DB/model/migration
MBA-52 Issue 0-2 permission helper 전환
MBA-53 Issue 0-3 member/invitation API
- 논리적 dependency:
- Issue 0-4 team/direct permission 검증 기준 변경이 생성되면 이 이슈의 blocker 또는 related issue로 연결해야 한다.
- 0-4 없이는 team membership API regression과 user direct permission regression을 최종 통과 처리하면 안 된다.
작업 범위
1. Migration / backfill regression test
목표: organization_memberships migration이 기존 데이터를 문서 의도대로 보존하고 중복 없이 backfill하는지 검증한다.
권장 테스트 위치:
tests/db/test_organization_membership_migration.py
- 또는 기존 DB 테스트 구조가 있으면 그 패턴을 따른다.
검증 시나리오:
- organization 생성자(
organizations.created_by)가 team member가 아니어도 active manager membership으로 backfill된다.
- organization 관리자(
organizations.managed_by)가 존재하면 active manager membership으로 backfill된다.
- 기존
team_memberships에 있는 사용자는 active member membership으로 backfill된다.
- 동일 사용자가 creator/manager/team member 조건을 모두 만족해도
(organization_id, user_id) membership row는 1개만 생긴다.
- role 우선순위가 필요하면 manager가 member보다 우선된다.
- deleted/inactive team membership row가 있다면 문서/모델 정책에 맞게 active membership으로 승격하지 않는다.
- migration 재실행 또는 idempotent 검증에서 duplicate row가 생기지 않는다.
- downgrade가 지원되는 경우
organization_memberships 테이블/인덱스/constraint가 정리되는지 확인한다.
완료 조건:
- migration test가 로컬 test suite에 포함된다.
- backfill 누락, duplicate, role downgrade, org mismatch를 잡을 수 있는 assertion이 있다.
2. Permission helper unit test
목표: permission 계산 앞단에서 active organization membership이 fail-closed gate로 동작하는지 검증한다.
권장 테스트 위치:
apps/shared/tests/services/test_permissions.py
- helper가 gateway/shared 중 어디에 구현되었는지에 따라 기존 permission 테스트 위치를 따른다.
필수 테스트 matrix:
| 상태 |
기존 permission row |
기대 결과 |
| active org member |
team viewer |
workflow viewer |
| no org membership |
team viewer row only |
none |
| active manager membership |
no explicit workflow row |
manager/admin equivalent per policy |
| invited membership |
user direct builder |
none |
| suspended membership |
team manager |
none |
| removed membership |
user direct builder |
none |
| active org member |
user direct builder, no team |
builder |
| active org member |
LLM direct permission |
LLM permission allowed |
| invited/suspended/removed member |
LLM direct permission |
none |
| org A active member |
org B workflow/team permission row |
none |
추가 검증:
has_active_organization_membership가 status/role/org mismatch를 정확히 판정한다.
get_organization_auth_state가 active/invited/suspended/removed/no-membership을 구분한다.
- 기존 MVP1 workflow/LLM permission helper public API가 불필요하게 깨지지 않는다.
- permission row가 남아 있어도 organization membership이 inactive이면 접근은 차단된다.
완료 조건:
- workflow permission, LLM permission, user direct permission, team permission 계산이 모두 active organization membership gate를 통과한다.
- negative case가 명시적으로 포함된다.
3. Organization member / invitation API test
목표: member/invitation service와 endpoint가 문서의 초대/수락/삭제 lifecycle을 만족하는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_organization_member_service.py
apps/gateway/tests/api/test_organization_members_api.py
- 기존 API 테스트 네이밍/fixture 패턴을 우선한다.
필수 API 시나리오:
- manager가 organization member list를 조회한다.
- manager가 기존 user를 organization에 invite한다.
- invited user는 accept 전 workflow/LLM/resource에 접근할 수 없다.
- invited user가 invitation을 accept한다.
- accept 이후 membership status가 active가 된다.
- manager가 active user에게 workflow direct builder permission을 부여한다.
- user는 workflow를 view/edit/run 할 수 있다.
- manager가 user를 organization에서 remove한다.
- removed user는 workflow/LLM/resource 접근이 즉시 차단된다.
- remove 시 user direct permission row가 정리된다.
- audit/activity에 invite, accept, permission grant, remove, cleanup 이벤트가 기록된다.
권한/가드 시나리오:
- manager가 아닌 사용자는 list/invite/update/remove를 수행할 수 없다.
- 자기 자신을 마지막 manager에서 제거하거나 demote하는 요청은 차단된다.
- 이미 active인 사용자를 다시 invite할 때 duplicate membership이 생기지 않는다.
- invited/suspended/removed 상태에서 accept/update/remove 정책이 문서와 일치한다.
- organization mismatch 요청은 404/403 정책에 맞게 처리한다.
완료 조건:
- API response shape가 FE 0-5에서 사용 가능한 형태로 고정된다.
- 실패 케이스의 status code와 error code/message가 테스트로 고정된다.
4. Team membership API regression
목표: team add/remove가 더 이상 “조직 소속 생성”처럼 동작하지 않고, active organization member만 대상으로 동작하는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_team_service_permissions.py
apps/gateway/tests/api/test_team_memberships.py
필수 시나리오:
- active organization member는 team에 추가할 수 있다.
- invited member는 team에 추가할 수 없다.
- suspended member는 team에 추가할 수 없다.
- removed member는 team에 추가할 수 없다.
- organization non-member는 team에 추가할 수 없다.
- team에서 제거해도 organization membership은 제거되지 않는다.
- 기존 team membership list/remove/update endpoint response shape가 MVP1 클라이언트와 호환된다.
완료 조건:
- team membership은 조직 소속을 암묵적으로 만들지 않는다.
- team membership 제거는 organization membership 제거와 분리된다.
5. User direct permission regression
목표: user direct permission grant 기준이 active organization membership으로 바뀌었는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_permission_service.py
apps/gateway/tests/api/test_workflow_permissions.py
- LLM permission이 별도 endpoint/service면 해당 테스트 파일 추가
필수 시나리오:
- active organization member는 team membership 없이 workflow direct builder permission을 받을 수 있다.
- active organization member는 team membership 없이 LLM direct permission을 받을 수 있다.
- invited member는 direct permission grant 대상이 될 수 없다.
- suspended member는 direct permission grant 대상이 될 수 없다.
- removed member는 direct permission grant 대상이 될 수 없다.
- organization non-member는 direct permission grant 대상이 될 수 없다.
- organization에서 remove된 사용자의 direct permission row는 cleanup된다.
- cleanup이 실패하면 access check는 그래도 fail-closed로 차단된다.
완료 조건:
- 0-2 helper와 0-4 service validation이 같은 기준을 사용한다.
- 기존 MVP1 permission grant/revoke API contract는 깨지지 않는다.
6. FE regression / Members UI smoke
목표: 0-5 UI가 API와 맞물려 실제 운영 플로우를 깨지 않는지 확인한다.
권장 테스트 위치:
apps/client Vitest/React Testing Library 테스트 구조
- Members UI component/page test
- permission picker filtering test
필수 시나리오:
- Members list가 active/invited/suspended/removed 상태를 표시한다.
- Invite modal이 성공/실패/loading/error state를 처리한다.
- invited/suspended/removed user는 team member picker에서 선택되지 않는다.
- invited/suspended/removed user는 workflow/LLM direct permission picker에서 선택되지 않는다.
- active organization member는 team 없이도 direct permission picker에서 선택 가능하다.
- remove 이후 UI에서 member 상태와 permission picker 후보가 갱신된다.
- 기존 MVP1 화면의 team/workflow/LLM permission UI가 렌더링된다.
완료 조건:
- client test/build가 통과한다.
- 수동 smoke에서 화면 상태가 API 상태와 어긋나지 않는다.
7. MVP1 demo smoke 재검증
목표: MVP2-0 foundation 추가 후 MVP1 사용자 흐름이 깨지지 않았는지 확인한다.
필수 smoke:
- signup/login 후 default organization/team context가 정상 설정된다.
- existing MVP1 workflow 생성/조회/수정/실행 플로우가 통과한다.
- existing MVP1 LLM credential/permission flow가 통과한다.
- team permission 기반 workflow access가 기존처럼 동작한다.
- user direct permission 기반 workflow/LLM access가 기존처럼 동작한다.
- audit/activity/logging이 기존 viewer에서 깨지지 않는다.
완료 조건:
- MVP1 demo script 또는 동등한 manual QA 결과를 이슈 코멘트에 남긴다.
- regression이 발견되면 원인 이슈에 연결하거나 별도 bug를 만든다.
권장 실행 명령
구현 위치와 fixture 상태에 따라 조정하되, 최소 아래 범위를 통과해야 한다.
Targeted checks:
PYTHONPATH=$PWD apps/gateway/.venv/bin/python -m pytest apps/gateway/tests/services apps/gateway/tests/api
PYTHONPATH=$PWD apps/gateway/.venv/bin/python -m pytest apps/shared/tests tests/db
cd apps/client && npm run test -- --run
cd apps/client && npm run build
필요하면 client lint도 추가한다.
cd apps/client && npm run lint
QA evidence
이슈 완료 전 코멘트 또는 PR description에 아래 evidence를 남긴다.
- migration revision id와 upgrade/downgrade 또는 upgrade-only 검증 결과
- 실행한 pytest/vitest/build 명령과 결과
- 수동 smoke 계정/fixture 요약
- invite -> accept -> direct grant -> team add -> remove 흐름 결과
- removed member 접근 차단 확인 결과
- 발견된 regression과 연결된 bug/issue 링크
Acceptance criteria
- Migration/backfill test가 통과한다.
- Permission helper unit test matrix가 통과한다.
- Organization member/invitation API lifecycle test가 통과한다.
- Team membership API regression test가 통과한다.
- User direct permission regression test가 통과한다.
- FE Members UI test/build/smoke가 통과한다.
- MVP1 workflow/LLM permission flow가 깨지지 않는다.
- invited/suspended/removed/no-membership user는 permission row가 남아 있어도 접근할 수 없다.
- organization에서 member removal 후 access가 즉시 차단된다.
- removal cleanup으로 direct permission row가 정리된다.
- audit/activity에 invite, accept, permission grant, remove, cleanup 이벤트가 확인된다.
- 실패한 항목이 있으면 완료 처리하지 않고 blocker/bug로 연결한다.
Non-goals
- Issue 0-1~0-5의 핵심 기능을 이 이슈에서 새로 구현하지 않는다. 단, 테스트를 통과시키기 위한 작은 fixture/test harness 수정은 허용한다.
- MVP2 knowledge/RAG/data-source permission enforcement 본작업은 이 이슈 범위가 아니다.
- email-only external invitation, active organization switcher, billing/plan 정책, 대규모 성능 테스트는 이 이슈 범위가 아니다.
- UI redesign이나 navigation 구조 변경은 이 이슈 범위가 아니다.
완료 후 다음 단계
0-6이 통과하면 MVP2 본작업의 data source / knowledge permission enforcement를 시작할 수 있다. 단, 0-2 permission helper와 0-4 team/direct permission validation 기준이 안정화되어 있어야 한다.
목적
MVP2-0 Organization Membership / Invitation Foundation 작업의 최종 회귀 검증 게이트를 만든다.
핵심은
team_memberships에 의존하던 “조직 소속” 기준을organization_memberships전제 계층으로 바꾼 뒤에도 MVP1 workflow/LLM permission flow가 깨지지 않는지 확인하는 것이다. 신규 organization member/invitation flow는 API/UI 레벨에서 통과해야 하며, member removal 이후에는 workflow/LLM/direct/team 기반 접근이 즉시 차단되어야 한다.문서 정합성
기준 문서:
docs/implementation-plan/mvp-2-0-organization-membership-plan.md이 이슈는 문서의 다음 항목과 직접 대응한다.
Issue 0-6. [Test][QA] MVP2-0 regression19. 테스트 상세22. 완료 기준23. Demo script24. 리스크와 대응이 이슈는 신규 제품 기능을 추가하는 이슈가 아니라, 0-1~0-5 구현 결과를 검증하고 문서 acceptance를 만족하는지 확인하는 회귀/QA 이슈다.
선행 조건 / 의존성
MBA-54Issue 0-5 FE Members UIMBA-51Issue 0-1 DB/model/migrationMBA-52Issue 0-2 permission helper 전환MBA-53Issue 0-3 member/invitation API작업 범위
1. Migration / backfill regression test
목표:
organization_membershipsmigration이 기존 데이터를 문서 의도대로 보존하고 중복 없이 backfill하는지 검증한다.권장 테스트 위치:
tests/db/test_organization_membership_migration.py검증 시나리오:
organizations.created_by)가 team member가 아니어도 active manager membership으로 backfill된다.organizations.managed_by)가 존재하면 active manager membership으로 backfill된다.team_memberships에 있는 사용자는 active member membership으로 backfill된다.(organization_id, user_id)membership row는 1개만 생긴다.organization_memberships테이블/인덱스/constraint가 정리되는지 확인한다.완료 조건:
2. Permission helper unit test
목표: permission 계산 앞단에서 active organization membership이 fail-closed gate로 동작하는지 검증한다.
권장 테스트 위치:
apps/shared/tests/services/test_permissions.py필수 테스트 matrix:
추가 검증:
has_active_organization_membership가 status/role/org mismatch를 정확히 판정한다.get_organization_auth_state가 active/invited/suspended/removed/no-membership을 구분한다.완료 조건:
3. Organization member / invitation API test
목표: member/invitation service와 endpoint가 문서의 초대/수락/삭제 lifecycle을 만족하는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_organization_member_service.pyapps/gateway/tests/api/test_organization_members_api.py필수 API 시나리오:
권한/가드 시나리오:
완료 조건:
4. Team membership API regression
목표: team add/remove가 더 이상 “조직 소속 생성”처럼 동작하지 않고, active organization member만 대상으로 동작하는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_team_service_permissions.pyapps/gateway/tests/api/test_team_memberships.py필수 시나리오:
완료 조건:
5. User direct permission regression
목표: user direct permission grant 기준이 active organization membership으로 바뀌었는지 확인한다.
권장 테스트 위치:
apps/gateway/tests/services/test_permission_service.pyapps/gateway/tests/api/test_workflow_permissions.py필수 시나리오:
완료 조건:
6. FE regression / Members UI smoke
목표: 0-5 UI가 API와 맞물려 실제 운영 플로우를 깨지 않는지 확인한다.
권장 테스트 위치:
apps/clientVitest/React Testing Library 테스트 구조필수 시나리오:
완료 조건:
7. MVP1 demo smoke 재검증
목표: MVP2-0 foundation 추가 후 MVP1 사용자 흐름이 깨지지 않았는지 확인한다.
필수 smoke:
완료 조건:
권장 실행 명령
구현 위치와 fixture 상태에 따라 조정하되, 최소 아래 범위를 통과해야 한다.
Targeted checks:
필요하면 client lint도 추가한다.
QA evidence
이슈 완료 전 코멘트 또는 PR description에 아래 evidence를 남긴다.
Acceptance criteria
Non-goals
완료 후 다음 단계
0-6이 통과하면 MVP2 본작업의 data source / knowledge permission enforcement를 시작할 수 있다. 단, 0-2 permission helper와 0-4 team/direct permission validation 기준이 안정화되어 있어야 한다.