npm package: @hsa-technologies-00/mongoose-automatic-reference
Description: Mongoose plugin for automatic reference IDs like CERT-1, CERT-2 etc.
Author: Md Harun Or Rashid
Latest version: 1.0.0

# Mongoose Automatic Reference Plugin

## Table of Contents

1. [Overview](#overview)
2. [Installation](#installation)
3. [Usage](#usage)
4. [API Documentation](#api-documentation)
5. [Examples](#examples)
6. [Advanced Configuration](#advanced-configuration)
7. [Testing](#testing)
8. [Contributing](#contributing)
9. [License](#license)

## Overview

The `@hsa-technologies-00/mongoose-automatic-reference` plugin automatically generates incrementing reference IDs for your Mongoose documents (e.g., "DOC-1", "DOC-2"). It maintains counters in a separate MongoDB collection and provides thread-safe ID generation.

Key Features:

- Automatic reference field generation
- Configurable prefix (e.g., "DOC", "INV", "CERT")
- Customizable starting sequence number
- Thread-safe counter operations
- TypeScript support

## Installation

```bash
npm install @hsa-technologies-00/mongoose-automatic-reference
```

or

```bash
yarn add @hsa-technologies-00/mongoose-automatic-reference
```

## Usage

### Basic Usage

```typescript
import mongoose from "mongoose";
import automaticReference from "@hsa-technologies-00/mongoose-automatic-reference";

const schema = new mongoose.Schema({ name: String });
schema.plugin(automaticReference, {
  fieldName: "docId", // Field to store the generated ID
  prefix: "DOC", // Prefix for the ID (e.g., DOC-1)
});

const Model = mongoose.model("Document", schema);

// When creating documents
const doc = await Model.create({ name: "Test" });
console.log(doc.docId); // Outputs "DOC-1"
```

### With Custom Initial Value

```typescript
schema.plugin(automaticReference, {
  fieldName: "certificateId",
  prefix: "CERT",
  initialValue: 1000, // Start counting from 1000 (CERT-1000)
});
```

## API Documentation

### Plugin Options

| Option         | Type   | Required | Default | Description                              |
| -------------- | ------ | -------- | ------- | ---------------------------------------- |
| `fieldName`    | string | Yes      | -       | The field name to store the generated ID |
| `prefix`       | string | Yes      | -       | The prefix for the reference ID          |
| `initialValue` | number | No       | 1       | Starting number for the sequence         |

## Examples

### Multiple Models with Different Prefixes

```typescript
// Certificates model
const certificateSchema = new mongoose.Schema({ name: String });
certificateSchema.plugin(automaticReference, {
  fieldName: "certId",
  prefix: "CERT",
});

// Invoices model
const invoiceSchema = new mongoose.Schema({ amount: Number });
invoiceSchema.plugin(automaticReference, {
  fieldName: "invoiceNumber",
  prefix: "INV",
  initialValue: 1000,
});

const Certificate = mongoose.model("Certificate", certificateSchema);
const Invoice = mongoose.model("Invoice", invoiceSchema);

// Usage
const cert = await Certificate.create({ name: "SSL Cert" });
const inv = await Invoice.create({ amount: 100 });

console.log(cert.certId); // e.g., "CERT-1"
console.log(inv.invoiceNumber); // e.g., "INV-1000"
```

### Using in an Existing Collection

```typescript
const existingSchema = new mongoose.Schema({
  /* ... */
});

// Add the plugin to existing collection
existingSchema.plugin(automaticReference, {
  fieldName: "legacyId",
  prefix: "LEG",
  initialValue: 5000, // Start after existing IDs
});
```

## Advanced Configuration

### Transaction Support

```typescript
const session = await mongoose.startSession();
session.startTransaction();

try {
  const doc = await Model.create([{ name: "Tx Test" }], { session });
  await session.commitTransaction();
  console.log(doc[0].docId);
} catch (error) {
  await session.abortTransaction();
  throw error;
} finally {
  session.endSession();
}
```

### Custom ID Formatting

Extend the plugin with custom formatting:

```typescript
schema.plugin(automaticReference, {
  fieldName: "customId",
  prefix: "CUST",
  formatter: (prefix: string, num: number) => {
    const year = new Date().getFullYear();
    return `${year}-${prefix}-${String(num).padStart(5, "0")}`;
    // e.g., "2023-CUST-00001"
  },
});
```

## Testing

To run tests:

```bash
npm test
```

Test environment requires:

- MongoDB instance running (default: `mongodb://localhost:27017/test_db`)
- Jest configured for TypeScript

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/xyz`)
3. Commit your changes (`git commit -am 'Add feature xyz'`)
4. Push to the branch (`git push origin feature/xyz`)
5. Open a Pull Request

## License

MIT © Md. Harun Or Rashid

---

## Support

If you find this package useful, please consider giving it a ⭐️ on [GitHub](https://github.com/hsa-technologies-00/mongoose-automatic-reference).

---

Enjoy building Mongoose plugins with ease! 🚀