# Example: Bad PR with Incomplete Documentation

This is an example of a poorly documented pull request that violates documentation requirements.

## PR Title

```
fix stuff
```

**❌ Bad because:**
- No semantic prefix
- Vague ("stuff")
- Doesn't describe what was fixed

**✅ Should be:**
```
fix: resolve JWT token expiration validation bug
```

## PR Description

````markdown
Fixed a bug.

---

## Documentation Checklist

- [ ] README.md updated if user-facing changes
- [ ] API documentation updated if endpoints/interfaces changed
- [ ] Architecture docs updated if design patterns changed
- [ ] Code comments added for complex/non-obvious logic
- [ ] Docstrings updated for modified functions/classes

## PR Quality Checklist

- [x] Code follows project style guide
- [x] All tests pass locally
````

**❌ Bad because:**
- No explanation of WHAT bug was fixed
- No explanation of WHY it needed fixing
- No testing details
- No impact assessment
- Documentation checklist completely ignored (all unchecked)

**✅ Should be:**
````markdown
## Description

Fixed bug in JWT token validation that allowed expired tokens to authenticate.

### What Changed

**Core Fix:**
- Updated `validate_token()` in `src/auth/token.py` to properly check expiry
- Added explicit expiry validation before signature check
- Added test case for expired token scenario

**Documentation:**
- Updated API docs to clarify token expiry behavior
- Added docstring explaining expiry validation
- Updated security section in README

### Why

**Bug:** Expired JWT tokens were being accepted due to incorrect exception handling
**Impact:** Security vulnerability - users could remain authenticated after logout
**Severity:** High (allows unauthorized access)

### Impact

**Files changed:** 3 files (1 source, 1 test, 1 doc)
**Lines changed:** +23, -5

**Breaking changes:** None
**Migration required:** No (transparent fix)

### Testing

**Reproduction:**
1. Generate token with 1-second expiry
2. Wait 2 seconds
3. Attempt authentication with expired token
4. Before fix: ✓ Authenticated
5. After fix: ✗ Rejected (401 Unauthorized)

**Test results:**
```bash
$ pytest tests/auth/test_token.py::test_expired_token_rejected
===== 1 passed in 0.05s =====
```

---

## Documentation Checklist

- [x] README.md updated (security section)
- [x] API docs updated (clarified expiry behavior)
- [x] Docstring added explaining validation
- [x] Code comments for exception handling

## PR Quality Checklist

- [x] Code follows project style guide
- [x] All tests pass locally
- [x] Security vulnerability fixed
````

## Files Changed

### 1. Source Code (`src/auth/token.py`)

**Before (BAD - No docstrings, no comments):**
```python
import jwt
from datetime import datetime, timedelta


def generate_token(user_id):
    expiry = datetime.utcnow() + timedelta(hours=24)
    payload = {"user_id": user_id, "exp": expiry}
    return jwt.encode(payload, "secret-key", algorithm="HS256")


def validate_token(token):
    try:
        payload = jwt.decode(token, "secret-key", algorithms=["HS256"])
        return payload.get("user_id")
    except:
        return None
```

**❌ Bad because:**
- No docstrings
- No type hints
- Hardcoded secret key
- Bare `except:` clause (catches everything)
- No comments explaining logic

**After (GOOD - With docstrings and comments):**
```python
"""JWT token generation and validation."""

import jwt
from datetime import datetime, timedelta
from typing import Optional
from ..config import settings


def generate_token(user_id: int) -> str:
    """Generate JWT token for authenticated user.

    Args:
        user_id: Unique identifier for the user

    Returns:
        Encoded JWT token string

    Example:
        >>> token = generate_token(123)
        >>> print(token)
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
    """
    # Token expires after 24 hours
    expiry = datetime.utcnow() + timedelta(hours=24)

    # Payload contains user_id and expiry
    # Following JWT best practices: no sensitive data in payload
    payload = {
        "user_id": user_id,
        "exp": expiry,
        "iat": datetime.utcnow()
    }

    # Sign with HS256 using secret from config (never hardcoded)
    return jwt.encode(payload, settings.JWT_SECRET, algorithm="HS256")


def validate_token(token: str) -> Optional[int]:
    """Validate JWT token and extract user ID.

    Args:
        token: JWT token string to validate

    Returns:
        User ID if token is valid, None if invalid or expired

    Example:
        >>> user_id = validate_token("eyJhbGciOiJIUzI1...")
        >>> print(user_id)
        123
    """
    try:
        # Decode verifies signature AND expiry automatically
        payload = jwt.decode(
            token,
            settings.JWT_SECRET,
            algorithms=["HS256"]
        )
        return payload.get("user_id")

    except jwt.ExpiredSignatureError:
        # Token expired - user needs to re-authenticate
        # This is normal and expected after token lifetime
        return None
    except jwt.InvalidTokenError:
        # Token is invalid - tampered, malformed, or wrong secret
        # Could indicate attack attempt
        return None
```

### 2. Documentation (`README.md`)

**Before (BAD - No auth documentation):**
```markdown
# My Project

A web application.

## Installation

```bash
pip install -r requirements.txt
```

## Usage

```bash
python app.py
```
```

**❌ Bad because:**
- No mention of authentication
- No configuration instructions
- No usage examples
- Users would be confused

**After (GOOD - Complete documentation):**
```markdown
# My Project

A web application with user authentication.

## Features

- User authentication with JWT tokens
- Secure password storage
- Protected API endpoints

## Installation

```bash
pip install -r requirements.txt
```

## Configuration

Create a `.env` file:

```bash
JWT_SECRET=your-secret-key-here
```

## Usage

```bash
# Start server
python app.py

# Register user
curl -X POST http://localhost:5000/api/auth/register \
  -d '{"username": "alice", "password": "secret"}'

# Login
curl -X POST http://localhost:5000/api/auth/login \
  -d '{"username": "alice", "password": "secret"}'
```

See [API Documentation](docs/api.md) for details.
```

### 3. API Documentation

**Before (BAD - No API docs at all):**

(File doesn't exist)

**❌ Bad because:**
- Users have no way to know what endpoints exist
- No request/response examples
- No error documentation

**After (GOOD - Complete API docs):**

See `good-pr-example.md` for full API documentation example.

## Common Documentation Mistakes

### ❌ Mistake #1: No Docstrings

```python
def process_data(data):
    result = []
    for item in data:
        if item > 0:
            result.append(item * 2)
    return result
```

**Problem:** No explanation of what function does, parameters, or return value.

### ❌ Mistake #2: Vague PR Descriptions

```markdown
## Description

Updated the auth system.
```

**Problem:** No details about what changed, why, or impact.

### ❌ Mistake #3: Ignoring Documentation Checklist

```markdown
## Documentation Checklist

- [ ] README.md updated
- [ ] API docs updated
- [ ] Docstrings added
```

**Problem:** All items unchecked but PR submitted anyway.

### ❌ Mistake #4: Outdated Documentation

```python
def calculate_discount(price):
    """Calculate 10% discount."""
    return price * 0.15  # Actually 15%, not 10%!
```

**Problem:** Docstring doesn't match implementation.

### ❌ Mistake #5: No Usage Examples

```markdown
## Installation

Install the dependencies.

## Usage

Run the application.
```

**Problem:** No concrete examples or commands.

### ❌ Mistake #6: Missing Configuration

```markdown
## Usage

```bash
python app.py
```
```

**Problem:** Doesn't explain required environment variables or configuration files.

### ❌ Mistake #7: No Error Documentation

```markdown
### POST /api/users

Create a user.

Response: `201 Created`
```

**Problem:** Doesn't document error responses (400, 401, 422, etc.).

## How to Fix a Bad PR

If your PR is missing documentation:

1. **Read the checklist** in the PR template
2. **Check each item**:
   - Did you update README? If not, do it now
   - Did you add docstrings? If not, add them
   - Did you update API docs? If not, update them
3. **Add examples** showing how to use new features
4. **Document errors** and edge cases
5. **Update the PR description** to explain what/why/impact
6. **Re-check the checklist** - all items should be ✅

## Why Documentation Matters

**Without docs:**
- New developers can't onboard
- Users don't know how to use features
- Code becomes unmaintainable
- Knowledge is lost when developers leave

**With docs:**
- Clear onboarding path
- Self-service for users
- Code is maintainable
- Knowledge is preserved

## Related Documentation

- **Good PR example**: `examples/documentation/good-pr-example.md`
- **PR template**: `.github/PULL_REQUEST_TEMPLATE.md`
- **Playbook**: `playbooks/updating-documentation.md`
- **Knowledge base**: `.claude/knowledge/documentation/keeping-docs-updated.md`
- **Engineering standards**: `.claude/standards/ENGINEERING_STANDARDS.md#documentation-requirements`
- **Rule #11**: `.claude/standards/CLAUDE_CODE_RULES.md#11-documentation-updates`
