# VS-01: Manage Identity and Roles - Vertical Slice Specification

**Slice ID:** VS-01  
**Batch:** 1 (no dependencies)  
**Status:** 📋 SPECIFICATION  
**Created:** 2026-08-04  

---

## Executive Summary

Establish centralized **Identity and Role Management (IAM)** system for K-ArtSell platform.

**User Goal:** Administrators can manage user accounts, roles, and permissions from a single dashboard without manual database operations.

**Non-Goal:**
- SSO/LDAP integration (Phase 3)
- MFA implementation (Phase 3)  
- Audit trail (separate feature)
- Password reset workflow (Phase 3)

---

## Acceptance Criteria

### 1. User Management ✅

- [ ] **Create User:** Endpoint creates new user record with UUID, email, hashed password, roles
- [ ] **Read Users:** Paginated list, filterable by role/status
- [ ] **Update User:** Change email, roles (no password update here)
- [ ] **Soft Delete:** Mark user as inactive (no hard delete)
- [ ] **Validation:** Email unique per environment, password ≥12 chars

### 2. Role & Permission Model ✅

- [ ] **Predefined Roles:** Admin, Analyst, Trader, Viewer (immutable)
- [ ] **Permissions:** Read, Write, Approve, Execute (scoped to domain)
- [ ] **User-Role Mapping:** Many-to-many with assigned_at timestamp
- [ ] **Permission Enforcement:** Checked on every endpoint (via PermissionGuard)

### 3. Data Integrity ✅

- [ ] **PIT Compliance:** created_at (never future), updated_at, published_at (for CDC)
- [ ] **Immutable:** user_id, email_hash cannot change post-creation
- [ ] **Revision Tracking:** Each role change creates new record (append-only)
- [ ] **Schema-Qualified:** All queries use `identity.users`, `identity.roles`

### 4. API Contracts ✅

**Endpoint: POST /api/users**
```
Request: { email: string, password: string, roles: ["Admin", "Analyst"] }
Response: 201 Created { userId: UUID, email: string, roles: [string] }
Errors: 400 (invalid), 409 (exists), 422 (validation)
Idempotency: IdempotencyKey header
```

**Endpoint: GET /api/users?page=1&limit=20&role=Admin**
```
Response: 200 { items: [User], total: int, page: int, limit: int }
Errors: 401, 403 (insufficient permissions)
```

**Endpoint: PATCH /api/users/:id**
```
Request: { roles: ["Analyst", "Viewer"], status: "active" }
Response: 200 { userId: UUID, roles: [string], updated_at: timestamp }
```

### 5. UI/UX Acceptance Criteria ✅

- [ ] **User List Page:** Table with columns (Email, Roles, Status, Actions)
- [ ] **Create Dialog:** Form with email + password + role multi-select
- [ ] **Edit Dialog:** Change roles inline
- [ ] **Delete Dialog:** Confirm soft-delete with warning
- [ ] **Accessibility:** ARIA labels, keyboard nav, error messages

### 6. Security Acceptance Criteria ✅

- [ ] **Password Hashing:** bcrypt or argon2, never plaintext
- [ ] **Auth Check:** Every endpoint requires role (no anonymous)
- [ ] **Authorization:** Only Admin can modify users
- [ ] **Audit Logging:** User changes logged with correlationId
- [ ] **No PII in Logs:** Email, password NEVER logged

---

## Failure Modes & Recovery

### Scenario 1: Duplicate Email

**Trigger:** POST /api/users with existing email  
**Expected:** 409 Conflict { error: "Email already exists" }  
**Recovery:** User retries with different email

### Scenario 2: Invalid Role

**Trigger:** POST /api/users with role="SuperAdmin" (not in predefined list)  
**Expected:** 422 Unprocessable { error: "Invalid role: SuperAdmin" }  
**Recovery:** User selects from dropdown of valid roles

### Scenario 3: Concurrent Role Update

**Trigger:** 2 admins modify same user's roles simultaneously  
**Expected:** Last-write-wins (UPDATE WHERE version = @version, increment version)  
**Recovery:** Second request gets 409 Conflict, user retries with fresh data

---

## Success Metrics

| Metric | Target | Verification |
|--------|--------|--------------|
| Create latency | <200ms | Load test |
| List latency | <500ms (1000 users) | Stress test |
| Auth check latency | <50ms | Endpoint latency trace |
| Test coverage | ≥95% | Code coverage report |
| Uptime | ≥99.9% | Monitoring dashboard |

---

## Dependencies

### Inbound (Block VS-01)

- ✅ **VS-00:** Platform foundation (complete)
- ✅ **Authentication:** DevelopmentHeader + FailClosed (Phase 1)

### Outbound (Unblock)

- 🔄 **VS-07:** ManageClientIPS (depends on VS-01 for User/Role APIs)
- 🔄 **VS-02~08:** All slices use VS-01's permission model

---

## Component Breakdown (7 items per slice)

| Component | Owner | Duration | Status |
|-----------|-------|----------|--------|
| **GOV** (this doc) | Architect | 1-2 hrs | 📋 |
| **DATA** | Data Architect | 2-3 hrs | ⏳ Ready |
| **DOMAIN** | Quant Lead | 2-3 hrs | ⏳ Ready |
| **BE** | BE Lead | 3-4 hrs | ⏳ Ready |
| **ASYNC** | SRE | 2-3 hrs | ⏳ Ready |
| **FE** | FE Architect | 3-4 hrs | ⏳ Ready |
| **TESTOPS** | QA Lead | 2-3 hrs | ⏳ Ready |

**Total Duration:** ~18-22 hours (wall-clock ~3 days)

---

## Sign-Off

| Role | Name | Status | Date |
|------|------|--------|------|
| Product Owner | User | ⏳ Approval | TBD |
| Architect | Claude Code | ✅ Draft | 2026-08-04 |
| Security | Team | ⏳ Review | TBD |

---

**Status:** 📋 **READY FOR DATA/DOMAIN/BE COMPONENTS**

Next: VS-01_DATA_CONTRACT.md
