diff --git a/.github/TS-Mock-API.png b/.github/TS-Mock-API.png
new file mode 100644
index 0000000..c68da49
Binary files /dev/null and b/.github/TS-Mock-API.png differ
diff --git a/README.md b/README.md
index ecc68e0..1f506d1 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,37 @@
-# TS-Mock-Proxy
+
+
+
-A "Zero-Config" mock server that instantly generates a functional REST API from your TypeScript interfaces. Write your types, get a working API. Perfect for frontend developers who need to work independently of the backend.
+TS-Mock-Proxy
----
-
-## Tech Stack
+
+ Instant REST API from TypeScript interfaces — no backend required.
+
-Built with TypeScript, Express, and Swagger UI. Uses Intermock for type analysis and Faker for realistic test data generation.
+
+ Quick Start ·
+ Reference ·
+ License
+
---
-## Quick Start
+Write a TypeScript interface, get a fully working REST API with realistic mock data, pagination, filtering, Swagger docs, and persistence. Ideal for frontend teams working independently of the backend.
-### Installation
+---
-```bash
-# Clone the project
-git clone
-cd ts-mock-proxy
+## ⚡ Quick Start
-# Install dependencies
-npm install
+### 1 — Install
-# Build the project
-npm run build
+```bash
+npm install -g ts-mock-proxy
+# or use directly with npx (no install needed)
```
-### Usage
-
-**Step 1: Define your TypeScript types**
+### 2 — Define your types
-Mark interfaces with `// @endpoint` to expose them as API endpoints:
+Mark any interface with `// @endpoint` to expose it as an API route:
```typescript
// types/user.ts
@@ -43,40 +44,52 @@ export interface User {
}
```
-**Step 2: Start the mock server**
-
-**Interactive Mode (Recommended)**
+### 3 — Start the server
```bash
-npm run dev
-# or
+# Interactive wizard (recommended for first run)
npx ts-mock-proxy
-```
-
-You'll be prompted for:
-- Types directory location
-- Server port (default: 8080)
-- Optional features (hot-reload, caching, latency simulation)
-**CLI Mode (Automation)**
+# Or directly via CLI
+npx ts-mock-proxy --types-dir ./types --port 3000
+```
-Use command-line options for scripting or CI/CD:
+### 4 — Call your API
```bash
-# Basic usage - specify your types directory
-npx ts-mock-proxy --types-dir ./types --port 3000
+GET /users # → paginated list of User
+GET /users/1 # → single User
+POST /users # → create (body echoed back)
+PUT /users/1 # → replace
+PATCH /users/1 # → partial update
+DELETE /users/1 # → delete
+```
-# Examples
-npx ts-mock-proxy --types-dir ./types --port 3000 --verbose
+> URL prefixes `api` and `v{n}` are stripped automatically — `/api/v1/users/1` works the same as `/users/1`.
-# With latency simulation
-npx ts-mock-proxy --types-dir ./types --port 3000 --latency 500-2000
+### 5 — Explore in Swagger
-# Disable features
-npx ts-mock-proxy --types-dir ./types --no-cache --no-hot-reload
+```
+http://localhost:8080/api-docs
```
-**Available CLI Options**
+All endpoints are documented and testable directly from the browser.
+
+---
+
+## 📖 Reference
+
+- [CLI Options](#cli-options)
+- [URL Patterns](#url-patterns)
+- [Pagination, Filtering & Sorting](#pagination-filtering--sorting)
+- [JSDoc Field Constraints](#jsdoc-field-constraints)
+- [Mock Modes](#mock-modes)
+- [JSON Persistence](#json-persistence)
+- [How It Works](#how-it-works)
+
+---
+
+### CLI Options
```
Options:
@@ -91,123 +104,71 @@ Options:
-h, --help Show help
```
-**Environment Variables**
+**Environment variables**
| Variable | Values | Description |
|---|---|---|
-| `MOCK_API_MODE` | `strict`, `dev` | Override mock mode without CLI flag |
+| `MOCK_API_MODE` | `strict`, `dev` | Override mock mode without a CLI flag |
Resolution order: CLI `--mock-mode` > `MOCK_API_MODE` env var > config file > default (`dev`).
-**Step 3: Call your API**
+---
+
+### URL Patterns
-The server enforces idiomatic REST URL patterns:
+The server only accepts idiomatic REST URLs. Each path segment is classified as a **collection name** (plural noun) or an **ID** (numeric, UUID, or MongoDB ObjectId).
-| URL | Result |
+| URL | Response |
|---|---|
-| `GET /users` | Array of `User` (paginated) |
+| `GET /users` | Paginated array of `User` |
| `GET /users/123` | Single `User` |
-| `GET /users/{uuid}` | Single `User` |
-| `GET /users/123/posts` | Array of `Post` (if `Post` is defined) |
-| `GET /user` | 404 — singular collection names are rejected |
-| `GET /users/123/posts/456` | 404 — nested single-item not supported |
-
-```bash
-# List (plural URL) — with pagination metadata
-curl http://localhost:8080/users
-# → {"data": [...], "meta": {"total": 100, "page": 1, "pageSize": 20, "totalPages": 5}}
-
-# Single item by numeric ID
-curl http://localhost:8080/users/1
-# → {"id": 482, "name": "John Doe", "email": "john.d@gmail.com", "role": "admin"}
-
-# Single item by UUID
-curl http://localhost:8080/users/550e8400-e29b-41d4-a716-446655440000
-# → {"id": 482, "name": "John Doe", ...}
-
-# Nested collection (requires Post interface with @endpoint)
-curl http://localhost:8080/users/1/posts
-# → {"data": [...], "meta": {...}}
-```
-
-URL prefix segments `api` and `v{n}` are stripped automatically, so `/api/v1/users/1` works the same as `/users/1`.
-
-**Step 4: View API Documentation**
-
-Access the auto-generated Swagger UI:
-
-```
-http://localhost:8080/api-docs
-```
-
-All endpoints are documented with examples and you can test them directly from your browser.
+| `GET /users/550e8400-…` | Single `User` (UUID) |
+| `GET /users/123/posts` | Paginated array of `Post` |
+| `GET /user` | **404** — singular names are rejected |
+| `GET /users/123/posts/456` | **404** — nested single items are not supported |
---
-## Pagination, Filtering & Sorting
+### Pagination, Filtering & Sorting
-All list endpoints (plural routes that return an array) support pagination, filtering, and sorting via query parameters. Responses always use the envelope format:
+All collection endpoints (`GET /resources`) support these query parameters. Responses always use the envelope format:
```json
{
"data": [...],
- "meta": {
- "total": 100,
- "page": 2,
- "pageSize": 20,
- "totalPages": 5
- }
+ "meta": { "total": 100, "page": 2, "pageSize": 20, "totalPages": 5 }
}
```
-The server generates a pool of 100 mock items and applies your filters/sort/pagination to that pool, so `total` and `totalPages` reflect realistic numbers.
+The server maintains an in-memory pool of 100 mock items per type — filters, sort, and pagination operate on that pool, so `total` reflects a realistic number.
-### Pagination
+#### Pagination
| Param | Default | Max | Description |
|---|---|---|---|
| `page` | `1` | — | Page number (1-based) |
| `pageSize` | `20` | `100` | Items per page |
-```bash
-GET /users?page=2&pageSize=50
-```
-
-### Filtering
+#### Filtering
-| Convention | Applies to | Example | Description |
+| Convention | Type | Example | Description |
|---|---|---|---|
-| `field=value` | string, number, boolean | `status=active` | Exact match (case-insensitive for strings) |
-| `field_contains=value` | string | `email_contains=@example.com` | Substring match (case-insensitive) |
-| `field_gte=value` | number, date | `price_gte=10`, `createdAt_gte=2024-01-01` | Greater than or equal |
-| `field_lte=value` | number, date | `price_lte=100`, `createdAt_lte=2024-12-31` | Less than or equal |
-
-Multiple filters are combined with AND logic. Unknown fields are silently ignored. Date values must be ISO 8601.
-
-```bash
-GET /users?status=active&email_contains=@example.com&createdAt_gte=2024-01-01
-GET /products?price_gte=10&price_lte=100&status=active
-```
-
-### Sorting
-
-Use `sort=field:dir` with comma-separated entries for multi-field sort. Direction must be `asc` or `desc`.
+| `field=value` | string / number / boolean | `role=admin` | Exact match (case-insensitive for strings) |
+| `field_contains=value` | string | `email_contains=@example.com` | Substring match |
+| `field_gte=value` | number / date | `createdAt_gte=2024-01-01` | Greater than or equal |
+| `field_lte=value` | number / date | `price_lte=100` | Less than or equal |
-```bash
-GET /users?sort=createdAt:desc,lastName:asc
-```
+Multiple filters combine with AND logic. Unknown fields are ignored. Dates must be ISO 8601.
-Sorting by a field that does not exist in the interface returns `400`.
-
-### Combined Example
+#### Sorting
```bash
-GET /users?page=2&pageSize=50&status=active&email_contains=@example.com&sort=createdAt:desc
+GET /users?sort=createdAt:desc,name:asc
```
-### Error Responses
+Sorting by a field that doesn't exist in the interface returns `400`.
-Invalid query parameters return `400` with a descriptive message:
+#### Error responses
```json
{ "error": "Invalid query parameters", "message": "\"pageSize\" must not exceed 100" }
@@ -216,104 +177,81 @@ Invalid query parameters return `400` with a descriptive message:
---
-## 🎯 Field Constraints with JSDoc Annotations
-
-Add validation constraints to your interfaces using JSDoc annotations. This ensures generated mock data follows your API rules.
+### JSDoc Field Constraints
-### Supported Constraints
+Add constraints to interface fields using JSDoc annotations. Generated mock data will always respect these rules.
-| Annotation | Type | Example | Description |
-|---|---|---|---|
-| `@minLength` | string | `@minLength 3` | Minimum string length |
-| `@maxLength` | string | `@maxLength 10` | Maximum string length |
-| `@pattern` | string | `@pattern ^[a-z]+$` | Regex pattern validation |
-| `@min` | number | `@min 1` | Minimum numeric value |
-| `@max` | number | `@max 100` | Maximum numeric value |
-| `@enum` | any | `@enum ACTIVE,INACTIVE,PENDING` | Allowed values (comma-separated) |
-
-### Usage Examples
+| Annotation | Type | Example |
+|---|---|---|
+| `@min` / `@max` | number | `@min 1 @max 100` |
+| `@minLength` / `@maxLength` | string | `@minLength 3 @maxLength 20` |
+| `@pattern` | string | `@pattern ^[a-z]+$` |
+| `@enum` | any | `@enum ACTIVE,INACTIVE,PENDING` |
```typescript
// @endpoint
-export interface Badge {
- /** @maxLength 10 */
- label: string;
-
- /** @min 1 @max 5 */
- level: number;
-
- /** @enum ACTIVE,INACTIVE,PENDING */
+export interface Product {
+ /** @maxLength 50 */
+ title: string;
+
+ /** @min 0.01 @max 999999.99 */
+ price: number;
+
+ /** @enum DRAFT,PUBLISHED,ARCHIVED */
status: string;
+
+ /** @minLength 10 @maxLength 500 */
+ description: string;
}
```
-Response:
+Generated response:
```json
-{ "label": "New", "level": 3, "status": "ACTIVE" }
+{ "title": "Wireless Headphones", "price": 49.99, "status": "PUBLISHED", "description": "A detailed product description..." }
```
-### More Examples
+> Constraints are applied during generation, not enforced at validation time. Mock data is always returned — never rejected.
-```typescript
-// @endpoint
-export interface User {
- id: number;
-
- /** @minLength 3 @maxLength 20 */
- username: string;
-
- // not needed, email is one of the types handled by intermock
- email: string;
-
- /** @min 18 @max 120 */
- age: number;
-}
+---
-// @endpoint
-export interface Product {
- /** @maxLength 50 */
- title: string;
-
- /** @minLength 10 @maxLength 500 */
- description: string;
-
- /** @min 0.01 @max 999999.99 */
- price: number;
-
- /** @enum DRAFT,PUBLISHED,ARCHIVED */
- status: string;
-}
+### Mock Modes
+
+| Mode | Description |
+|---|---|
+| `dev` (default) | Full mock features: `x-mock-status` header, artificial latency |
+| `strict` | Clean REST simulation — mock features disabled, behaves like a real API |
+
+```bash
+npx ts-mock-proxy --types-dir ./types --mock-mode strict
+# or
+MOCK_API_MODE=strict npx ts-mock-proxy --types-dir ./types
```
-### How It Works
+#### Dev-mode features
-1. Constraints are extracted from JSDoc comments when generating mock data
-2. Intermock generates base mock data
-3. The constraint resolver applies your rules to ensure valid data
-4. **No validation** - constraints are applied, not enforced. Mocks always return valid data.
+**Force a response status** with the `x-mock-status` header:
+```bash
+curl -H "x-mock-status: 503" http://localhost:8080/users
+# → 503 response, regardless of the route
+```
+**Simulate network latency** via `--latency min-max` (milliseconds):
-## Available Commands
+```bash
+npx ts-mock-proxy --types-dir ./types --latency 200-800
+```
-- `npm run dev` - Start development server
-- `npm run build` - Compile TypeScript
-- `npm start` - Start production server
-- `npm test` - Run all tests
-- `npm test -- queryProcessor.test.ts` - Test pagination/filtering/sorting
-- `npm test -- constraintExtractor.test.ts` - Test constraint JSDoc extraction
-- `npm test -- constraintValidator.test.ts` - Test constraint validation
-- `npm test -- constrainedGenerator.test.ts` - Test constrained data generation
+In `strict` mode these features are never mounted — not just disabled, they don't exist in the request pipeline.
---
-## JSON Persistence
+### JSON Persistence
-By default, mock data is purely in-memory and resets on every server restart. Enable persistence to keep data between sessions or share a stable dataset across restarts.
+By default mock data is in-memory and resets on restart. Enable persistence to keep data between sessions.
-### Activation
+#### Enable
-**CLI:**
```bash
npx ts-mock-proxy --types-dir ./types --persist-data
# Uses default path: .mock-data.json
@@ -322,16 +260,16 @@ npx ts-mock-proxy --types-dir ./types --persist-data ./data/mocks.json
# Custom path
```
-**Wizard:** enable in the advanced options section.
-
-**Config file** (`.mock-config.json`):
+Via config file (`.mock-config.json`):
```json
{ "persistData": ".mock-data.json" }
```
-### File Format
+Or through the interactive wizard (advanced options section).
-The file is a flat JSON object keyed by TypeScript interface name:
+#### File format
+
+A flat JSON object keyed by TypeScript interface name:
```json
{
@@ -345,97 +283,50 @@ The file is a flat JSON object keyed by TypeScript interface name:
}
```
-You can edit this file manually while the server is stopped. Changes are loaded on the next startup.
+You can edit this file manually while the server is stopped — changes are picked up on the next startup.
-> **Warning:** if the server is running and a mutation (POST/PUT/PATCH/DELETE) occurs between your manual edit and the next restart, the automatic save will overwrite your edits. Stop the server before editing the file.
+> **Warning:** if a mutation (POST/PUT/PATCH/DELETE) happens while the server is running, it will overwrite the file. Stop the server before editing manually.
-### Behaviour
+#### Behaviour reference
| Situation | Result |
|---|---|
| First launch, no file | File created with generated data |
-| Restart, file present | Pools replaced by file content |
-| New type added to `typesDir` | Generated and added to file at startup |
+| Restart, file present | Pools loaded from file |
+| New type added to `typesDir` | Generated and appended to file at startup |
| POST / PUT / PATCH / DELETE | File updated atomically after every mutation |
| `POST /mock-reset` | File overwritten with freshly generated data |
| `POST /mock-reset/User` | Only `User` regenerated and saved |
-| `[]` in file | Preserved as-is — not regenerated (intentional empty state) |
-| Invalid JSON in file | Warning emitted, server starts normally, file not overwritten |
+| `[]` in file | Preserved — not regenerated (intentional empty state) |
+| Invalid JSON in file | Warning logged, server starts normally, file left untouched |
| Hot-reload (type file changed) | Affected types regenerated and saved; others untouched |
-Writes are atomic: the server writes to `.mock-data.json.tmp` first then renames it, so an interrupted write never corrupts the existing file.
+Writes are atomic: data goes to `.mock-data.json.tmp` first, then renamed, so an interrupted write never corrupts the existing file.
-### Selective Rebuild
+#### Selective rebuild
-Regenerate one type without affecting others:
+Regenerate a single type without touching the others:
```bash
POST /mock-reset/User
# → {"message": "Mock data regenerated for type \"User\"", "type": "User", "count": 10}
```
-The Swagger UI also exposes a type selector dropdown ("Select type… → Rebuild selected") next to the existing "Rebuild Data" (all) button.
+The Swagger UI also exposes a type selector dropdown → **Rebuild selected** next to the global **Rebuild Data** button.
---
-## Mock Modes
-
-The server supports two modes controlled by `mockMode`:
-
-| Mode | Description |
-|---|---|
-| `dev` (default) | All mock features enabled: `x-mock-status` header, artificial latency |
-| `strict` | Clean REST simulation — mock features disabled, behaviour matches a real API |
-
-In `strict` mode, the `statusOverride` and `latency` middlewares are not mounted at all.
-
-```bash
-# CLI
-npx ts-mock-proxy --types-dir ./types --mock-mode strict
-
-# Environment variable
-MOCK_API_MODE=strict npx ts-mock-proxy --types-dir ./types
-```
-
-### Mock features (dev mode only, non-prod)
-
-These features are active only in `dev` mode and should not be used to simulate real API behaviour:
-
-**`x-mock-status`** — forces any response to return the specified HTTP status code:
-
-```bash
-# Force a 503 response
-curl -H "x-mock-status: 503" http://localhost:8080/users
-```
-
-**Artificial latency** — simulates network delay (configured via `--latency` or the wizard):
-
-```bash
-npx ts-mock-proxy --types-dir ./types --latency 200-800
-```
+### How It Works
----
+1. **Type discovery** — the server scans `typesDir` recursively for `.ts` files. Only interfaces annotated with `// @endpoint` (or a JSDoc `@endpoint` block) are exposed.
-## How It Works
+2. **URL routing** — `api` and `v{n}` prefix segments are stripped. Remaining segments are classified as collection names (plural noun) or IDs (numeric / UUID / ObjectId). Anything that doesn't match a known pattern returns 404.
-The server enforces idiomatic REST URL patterns. URLs are parsed into segments (stripping `api` and `v{n}` prefixes) and each segment is classified as either a **collection name** or an **ID** (numeric, UUID, or MongoDB ObjectId).
+3. **Mock generation** — Intermock parses the TypeScript AST to understand your interface shape. Faker generates realistic field values. JSDoc constraint annotations (`@min`, `@max`, `@enum`, etc.) are applied post-generation to ensure conformance.
-Supported shapes:
+4. **Data pools** — each `@endpoint` type gets a pool of 100 mock items on first request. Filters, sorting, and pagination operate on this pool, so collection sizes feel realistic across pages.
-| URL shape | Resolves to |
-|---|---|
-| `/resources` | Array of the matching interface (plural names only) |
-| `/resources/{id}` | Single instance of the matching interface |
-| `/resources/{id}/sub-resources` | Array of the sub-resource interface |
-| Anything else | 404 |
-
-Only interfaces marked with `// @endpoint` are exposed. The server uses Intermock to parse TypeScript AST and Faker to generate realistic test data.
-
-**Constraint Processing**: When a request is made, the system:
-1. Extracts JSDoc annotations from each field in the interface
-2. Generates initial mock data using Intermock/Faker
-3. Applies constraints (length, range, enum, pattern) to ensure valid test data
-4. Caches schemas in memory for performance
+5. **Write operations** — POST/PUT/PATCH/DELETE mutate an in-memory write store on top of the pool. The merged view (write store + pool − deleted IDs) is what GET collection endpoints return.
---