- 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>
137 lines
5.1 KiB
TypeScript
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)
|
|
}
|
|
}
|
|
}
|