# M02 Lab Assets — Sample Code for Documentation Exercise

## Exercise 3: Code to Document

Below is a Python module that works correctly but lacks proper documentation. Use prompt
engineering to generate comprehensive docs. Try at least two prompt iterations.

```python
# user_service.py — Document this module using AI prompt engineering

import re
import hashlib
from datetime import datetime, timedelta
from typing import Optional

class UserService:
    def __init__(self, db_connection, email_provider=None):
        self.db = db_connection
        self.email = email_provider
        self._cache = {}
        self._cache_ttl = 300

    def create_user(self, username: str, email: str, password: str) -> dict:
        if not re.match(r'^[a-zA-Z0-9_]{3,32}$', username):
            raise ValueError("Invalid username format")
        if not re.match(r'^[^@]+@[^@]+\.[^@]+$', email):
            raise ValueError("Invalid email format")
        if len(password) < 8:
            raise ValueError("Password too short")

        existing = self.db.query("SELECT id FROM users WHERE username = ? OR email = ?",
                                  username, email)
        if existing:
            raise ValueError("Username or email already exists")

        pw_hash = hashlib.sha256(password.encode() + b'salt').hexdigest()
        user_id = self.db.insert("users", {
            "username": username,
            "email": email,
            "password_hash": pw_hash,
            "created_at": datetime.utcnow().isoformat()
        })

        user = {"id": user_id, "username": username, "email": email}
        self._cache[f"user:{user_id}"] = (user, datetime.utcnow())

        if self.email:
            self.email.send_welcome(email, username)

        return user

    def get_user(self, user_id: int) -> Optional[dict]:
        cached = self._cache.get(f"user:{user_id}")
        if cached and (datetime.utcnow() - cached[1]).seconds < self._cache_ttl:
            return cached[0]

        user = self.db.query("SELECT id, username, email, created_at FROM users WHERE id = ?",
                              user_id)
        if user:
            self._cache[f"user:{user_id}"] = (user, datetime.utcnow())
        return user

    def reset_password(self, user_id: int, new_password: str) -> bool:
        user = self.get_user(user_id)
        if not user:
            return False
        if len(new_password) < 8:
            raise ValueError("Password too short")
        pw_hash = hashlib.sha256(new_password.encode() + b'salt').hexdigest()
        self.db.update("users", user_id, {"password_hash": pw_hash})
        self._cache.pop(f"user:{user_id}", None)
        return True
```

Save this as `user_service.py` in your working directory. Then use prompt engineering
to generate documentation. Suggested prompts:

**Baseline:** "Document this code." (paste the code)  
**Refined:** Add role, format, audience, and level of detail to your prompt.
