# Admin Routes Contract
**Scope**: Product and user management web routes (User Story P4)
**Authentication**: Required (admin role only)
**Response Type**: Server-rendered HTML (no JavaScript required)
---
## GET /admin/products
Display list of all registered products.
### Request
**Authentication**: Required (admin role)
### Response
**Success (200 OK)**:
```html
Content-Type: text/html
```
### Functional Requirements Covered
- User management interface (implied by FR-048: assigning owners)
---
## GET /admin/users/new
Display form to create a new user.
### Request
**Authentication**: Required (admin role)
### Response
**Success (200 OK)**:
```html
Content-Type: text/html
Create New User
```
---
## POST /admin/users
Create a new user.
### Request
**Authentication**: Required (admin role)
**Form Data**:
- `email` (string, required): Valid email address (unique)
- `name` (string, required): Display name (1-100 characters)
- `password` (string, required): Password (min 8 characters)
- `role` (string, required): "product_owner" or "admin"
### Response
**Success (302 Redirect)**:
```http
HTTP/1.1 302 Found
Location: /admin/users
```
**Error (400 Bad Request)**: Validation failure
```html
Content-Type: text/html
Validation Error
Email must be unique
Password must be at least 8 characters
Invalid role specified
```
### Side Effects
- Appends new user to `data/users.yaml`
- Password hashed with bcrypt (cost factor 12) before storage (FR-063)
- Generates unique user ID (e.g., "owner-001", "admin-002")
### Functional Requirements Covered
- FR-063: Secure password storage (bcrypt)
- User creation for product owner assignment
---
## GET /admin/users/{user_id}/edit
Display form to edit an existing user.
### Request
**Authentication**: Required (admin role)
**Path Parameters**:
- `user_id` (string, required): User identifier
### Response
**Success (200 OK)**: Same form as create, pre-populated (except password field empty)
**Error (404 Not Found)**: User does not exist
---
## POST /admin/users/{user_id}
Update an existing user.
### Request
**Authentication**: Required (admin role)
**Path Parameters**:
- `user_id` (string, required): User identifier
**Form Data**:
- `email` (string, required): Valid email address
- `name` (string, required): Display name
- `password` (string, optional): New password (if changing)
- `role` (string, required): "product_owner" or "admin"
### Response
**Success (302 Redirect)**:
```http
HTTP/1.1 302 Found
Location: /admin/users
```
### Side Effects
- Updates user entry in `data/users.yaml`
- If password provided, re-hash with bcrypt
- Email and role can be updated
---
## POST /admin/users/{user_id}/delete
Delete a user.
### Request
**Authentication**: Required (admin role)
**Path Parameters**:
- `user_id` (string, required): User identifier
### Response
**Success (302 Redirect)**:
```http
HTTP/1.1 302 Found
Location: /admin/users
```
**Error (400 Bad Request)**: Cannot delete self
```html
Content-Type: text/html
Cannot Delete
You cannot delete your own account.
```
### Side Effects
- Removes user from `data/users.yaml`
- User automatically unassigned from all products
- Historical feedback metadata unchanged (no user tracking in feedback)
---
## Access Control
All admin endpoints enforce:
1. User must be authenticated (session cookie)
2. User role must be "admin"
3. Otherwise: 403 Forbidden response
### Functional Requirements Covered
- FR-045: Admin can register products
- FR-048: Admin can assign product owners
- FR-051: Admin can update products
- FR-052: Admin can archive products