Documentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-kit-redis-mongo-docker/llms.txt
Use this file to discover all available pages before exploring further.
BaseCRUD is a di-factory factory class that provides a complete set of generic MongoDB operations for any Mongoose model. All 15 DbService classes in the project extend BaseCRUD, inheriting its full CRUD surface and supplementing it with domain-specific methods such as upsert, findByContext, and listKeys. By centralising common database logic in a single factory, every service gets consistent logging, error handling, and the readTransform normalisation step without duplicating code.
Implementation
DbService calls BaseCRUD(Model) to produce a class that is already bound to a specific Mongoose model, which is then registered in the IoC container as a singleton.
The readTransform Helper
Every document returned by BaseCRUD passes through readTransform() before reaching the caller. This utility converts Mongoose’s internal _id field into a plain string id field while keeping all other properties intact:
id: string property and never need to interact with _id directly.
Methods
create(dto: object): Promise<any>
Creates a new document in the collection using the provided DTO. Returns the persisted document passed through readTransform.
update(id: string, dto: object): Promise<any>
Updates the document identified by MongoDB _id. Uses findByIdAndUpdate with { new: true, runValidators: true } so the returned document reflects the update and schema validators run. The id field is stripped from the update payload via omit(dto, "id") to prevent accidentally overwriting _id. Throws if no document is found.
findById(id: string): Promise<any>
Finds a single document by its MongoDB _id. Throws Error("<modelName> not found") if no document exists with that id.
findByFilter(filterData: object, sort?: object): Promise<any | null>
Finds the first document matching the filter object. Accepts an optional sort descriptor (e.g. { date: -1 }). Returns null if no document matches — unlike findById, this method does not throw on a miss.
findAll(filterData?: object, limit?: number): Promise<any[]>
Returns all documents matching filterData, sorted by date descending. The default limit is 1,000 documents (FIND_ALL_LIMIT). Pass a custom limit as the second argument if you need more or fewer results.
iterate(filterData?: object, sort?: object): AsyncGenerator<any>
An async generator that yields documents one at a time using Mongoose’s cursor-based iteration. Suitable for streaming large result sets without buffering the entire collection in memory.
paginate(filterData, pagination: { limit: number; offset: number }, sort?): Promise<{ rows: any[], total: number }>
Executes a paginated query. Returns an object with:
rows— the page of transformed documents.total— the total count of matching documents (used by UI pagination controls).
offset maps to Mongoose’s .skip() and limit to .limit().
Logging
Every method callsthis.loggerService.info(...) before executing the database query, logging the model name and key parameters. This provides an audit trail for every database operation without any configuration at the call site.
Extending BaseCRUD
Individual
DbService classes extend BaseCRUD and add domain-specific methods. For example, SignalDbService adds upsert(symbol, strategyName, exchangeName, payload) and findByContext(symbol, strategyName, exchangeName). MeasureDbService adds softRemove(bucket, key) and listKeys(bucket). The base class handles the generic operations; domain logic lives in the concrete service.