# 12 - M1.1 Revision Sheet & Interview Q&A

Is revision sheet me Milestone 1.1 ke saare critical points, commands, error troubleshooting, aur interview questions summarize kiye gaye hain.

---

## 1. M1.1 Summary Sheet

- **What We Built:** Tenant registration REST API endpoint (`POST /api/v1/tenant/register`).
- **Why We Built It:** Multi-tenant architecture me har website owner ko register karke unique `siteId` assign karne ke liye.
- **Core Stack Used:** Python, FastAPI, Pydantic, PyMongo (`AsyncMongoClient`), Certifi, Pytest, MongoDB Atlas/Local.
- **Architecture Flow:** Client Request -> FastAPI Router -> Pydantic Schema Validation -> Repository Layer -> MongoDB Database.

---

## 2. Key Commands Reference

```bash
# 1. Activate Virtual Environment (Windows PowerShell)
.\venv\Scripts\Activate.ps1

# 2. Install Dependencies
pip install -r requirements.txt

# 3. Run FastAPI Development Server
uvicorn app.main:app --reload --port 8000

# 4. Open Swagger UI Documentation
http://localhost:8000/docs

# 5. Run Automated Test Suite
pytest
```

---

## 3. Common Errors Encountered & Solutions

### Error 1: `SSL: CERTIFICATE_VERIFY_FAILED`
- **Why it happened:** Python SSL module failed to verify MongoDB Atlas cloud SSL certificates.
- **Solution:** Added `import certifi` and passed `tlsCAFile=certifi.where()` into `AsyncMongoClient(...)` in `app/database.py`.

### Error 2: `HTTP 422 Unprocessable Entity`
- **Why it happened:** Request body validation failed (e.g. empty string `name: ""` or missing mandatory fields).
- **Solution:** Send valid JSON payload containing both `domain` and non-empty `name`.

### Error 3: `HTTP 400 Bad Request: Tenant already registered for domain...`
- **Why it happened:** Attempted to register a domain that already exists in the database.
- **Solution:** Domain duplicate check in `app/routers/tenant.py` successfully blocked duplicate registration.

---

## 4. 10 Interview-Style Questions & Concise Answers

#### Q1: What is the primary purpose of Milestone 1.1?
**Answer:** To build a multi-tenant website registration endpoint (`POST /api/v1/tenant/register`) that validates inputs, prevents duplicate domains, generates a unique `siteId`, and persists the tenant in MongoDB.

#### Q2: Why do we separate routes (`routers/tenant.py`) and data access (`repositories/tenant_repository.py`)?
**Answer:** Adhering to the Repository Pattern decouples HTTP handling from database logic. This improves maintainability, allows changing database engines without altering routes, and simplifies unit testing.

#### Q3: How does domain normalization work in `TenantCreate`?
**Answer:** Pydantic's `@field_validator("domain")` cleans input strings by lowercasing, stripping leading `http://` or `https://`, and extracting only the base domain host before storing.

#### Q4: Why do we use `AsyncMongoClient` instead of synchronous `MongoClient`?
**Answer:** Asynchronous MongoDB operations prevent database I/O calls from blocking FastAPI's event loop, enabling high concurrency under heavy traffic.

#### Q5: What is the difference between `TenantCreate` and `TenantResponse`?
**Answer:** `TenantCreate` defines allowed user input fields for registration, while `TenantResponse` defines the exact fields (`siteId`, `domain`, `name`, `createdAt`) exposed to clients in the JSON output, omitting sensitive internal DB fields like `_id`.

#### Q6: Why is `certifi` used in database initialization?
**Answer:** `certifi` provides an up-to-date collection of Root Certificates, resolving SSL/TLS certificate verification errors when connecting to cloud-hosted databases like MongoDB Atlas.

#### Q7: How does `app/config.py` load configuration safely?
**Answer:** It inherits from Pydantic's `BaseSettings` to automatically read environment variables from a `.env` file without hardcoding credentials in source code.

#### Q8: What happens during `lifespan` startup and shutdown in `app/main.py`?
**Answer:** The `lifespan` async context manager executes startup setup before serving requests, and calls `close_database()` upon server termination to cleanly close open database socket connections.

#### Q9: How do automated tests prevent test data pollution in development database?
**Answer:** In `tests/conftest.py`, the test fixture overrides `settings.database_name = "chatbot_test_db"`, ensuring tests read/write to a dedicated test database.

#### Q10: How is `siteId` generated and structured?
**Answer:** In `tenant_repository.py`, it is generated as `f"site_{uuid.uuid4().hex[:12]}"` (e.g. `site_9a2b4c6d8e0f`), providing a clean, non-guessable multi-tenant isolation key.
