Files
adam-acs/database/base_model.ts
T
Kevin L'HereecandCopilot d1c65dbf1e chore: initial commit — AdonisJS v7 TR-069 ACS
- Docker infrastructure (Dockerfile, docker-compose.yml, genieacs-sim)
- AdonisJS v7 app with Inertia.js + Vue 3
- MongoDB integration
- CWMP/TR-069 state machine engine
- Configuration engine with compliance tracking
- Branding: ADAM ACS (favicon, navbar, locales)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 16:46:37 +02:00

137 lines
5.1 KiB
TypeScript

import { Db, Collection, ObjectId, Filter, UpdateFilter, Sort } from 'mongodb'
import { getMongoDb } from '#providers/mongodb_provider'
export abstract class BaseModel {
static collectionName: string
_id?: ObjectId
createdAt?: Date
updatedAt?: Date
static getDb(): Db {
return getMongoDb()
}
static getCollection(this: { collectionName: string; getDb(): Db }): Collection {
return this.getDb().collection(this.collectionName)
}
static async find(this: { collectionName: string; getDb(): Db }, filter: Filter<any> = {}): Promise<any[]> {
const collection = this.getDb().collection(this.collectionName)
return collection.find(filter).toArray()
}
static async findById(this: { collectionName: string; getDb(): Db }, id: string | ObjectId): Promise<any | null> {
const collection = this.getDb().collection(this.collectionName)
const objectId = typeof id === 'string' ? new ObjectId(id) : id
return collection.findOne({ _id: objectId })
}
static async findOne(this: { collectionName: string; getDb(): Db }, filter: Filter<any>): Promise<any | null> {
const collection = this.getDb().collection(this.collectionName)
return collection.findOne(filter)
}
static async create(this: { collectionName: string; getDb(): Db }, data: Partial<any>): Promise<any> {
const collection = this.getDb().collection(this.collectionName)
const now = new Date()
const doc = { ...data, createdAt: now, updatedAt: now }
const result = await collection.insertOne(doc)
return { ...doc, _id: result.insertedId }
}
static async createMany(this: { collectionName: string; getDb(): Db }, data: Partial<any>[]): Promise<any[]> {
const collection = this.getDb().collection(this.collectionName)
const now = new Date()
const docs = data.map((d) => ({ ...d, createdAt: now, updatedAt: now }))
const result = await collection.insertMany(docs)
return docs.map((doc, i) => ({ ...doc, _id: result.insertedIds[i] }))
}
static async updateOne(
this: { collectionName: string; getDb(): Db },
filter: Filter<any>,
update: UpdateFilter<any> | Partial<any>
): Promise<any> {
const collection = this.getDb().collection(this.collectionName)
const updateDoc = '$set' in update ? update : { $set: { ...update, updatedAt: new Date() } }
return collection.updateOne(filter, updateDoc)
}
static async updateMany(
this: { collectionName: string; getDb(): Db },
filter: Filter<any>,
update: UpdateFilter<any> | Partial<any>
): Promise<any> {
const collection = this.getDb().collection(this.collectionName)
const updateDoc = '$set' in update ? update : { $set: { ...update, updatedAt: new Date() } }
return collection.updateMany(filter, updateDoc)
}
static async deleteOne(this: { collectionName: string; getDb(): Db }, filter: Filter<any>): Promise<boolean> {
const collection = this.getDb().collection(this.collectionName)
const result = await collection.deleteOne(filter)
return result.deletedCount === 1
}
static async deleteMany(this: { collectionName: string; getDb(): Db }, filter: Filter<any>): Promise<number> {
const collection = this.getDb().collection(this.collectionName)
const result = await collection.deleteMany(filter)
return result.deletedCount
}
static async paginate(
this: { collectionName: string; getDb(): Db },
page: number,
perPage: number,
filter: Filter<any> = {},
sort: Sort = {}
): Promise<{ data: any[]; total: number; page: number; perPage: number; lastPage: number }> {
const collection = this.getDb().collection(this.collectionName)
const total = await collection.countDocuments(filter)
const lastPage = Math.max(1, Math.ceil(total / perPage))
const skip = (page - 1) * perPage
const data = await collection.find(filter).sort(sort).skip(skip).limit(perPage).toArray()
return { data, total, page, perPage, lastPage }
}
static query(this: { collectionName: string; getDb(): Db }) {
const collection = this.getDb().collection(this.collectionName)
return collection
}
async save(): Promise<void> {
const constructor = this.constructor as typeof BaseModel
const collection = constructor.getDb().collection(constructor.collectionName)
this.updatedAt = new Date()
if (!this.createdAt) {
this.createdAt = new Date()
}
const { _id, ...data } = this as any
if (_id) {
await collection.updateOne({ _id }, { $set: data })
} else {
const result = await collection.insertOne(data)
this._id = result.insertedId
}
}
async delete(): Promise<boolean> {
const constructor = this.constructor as typeof BaseModel
const collection = constructor.getDb().collection(constructor.collectionName)
if (!this._id) return false
const result = await collection.deleteOne({ _id: this._id })
return result.deletedCount === 1
}
async refresh(): Promise<void> {
const constructor = this.constructor as typeof BaseModel
const collection = constructor.getDb().collection(constructor.collectionName)
if (!this._id) return
const doc = await collection.findOne({ _id: this._id })
if (doc) {
Object.assign(this, doc)
}
}
}