feat(repo): implémentation MongoDB de CardRepository
This commit is contained in:
1 parent
ab24d329b9
commit
dca234f298
1 file changed
+126
@@ -0,0 +1,126 @@
|
||||
import { MongoClient, type Collection } from 'mongodb'
|
||||
import type { Card, CardInput } from '../domain/card'
|
||||
import type { CardRepository } from '../domain/card-repository'
|
||||
|
||||
interface CardDocument {
|
||||
c_id: string
|
||||
question: string
|
||||
response: string
|
||||
theme: string
|
||||
tags: string[]
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
const DOC_FIELDS = {
|
||||
_id: 0,
|
||||
c_id: 1,
|
||||
question: 1,
|
||||
response: 1,
|
||||
theme: 1,
|
||||
tags: 1,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
}
|
||||
|
||||
export class MongoCardRepository implements CardRepository {
|
||||
private readonly collection: Collection<CardDocument>
|
||||
|
||||
constructor(collection?: Collection<CardDocument>) {
|
||||
if (collection) {
|
||||
this.collection = collection
|
||||
} else {
|
||||
const client = new MongoClient(
|
||||
process.env.MONGODB_URI ?? 'mongodb://flashcards:flashcards@localhost:127017/flashcards',
|
||||
)
|
||||
this.collection = client
|
||||
.db(process.env.MONGODB_DATABASE ?? 'flashcards')
|
||||
.collection<CardDocument>('cards')
|
||||
}
|
||||
}
|
||||
|
||||
private mapDoc(doc: CardDocument): Card {
|
||||
return {
|
||||
id: doc.c_id,
|
||||
question: doc.question,
|
||||
response: doc.response,
|
||||
theme: doc.theme,
|
||||
tags: doc.tags,
|
||||
createdAt: doc.createdAt,
|
||||
updatedAt: doc.updatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(): Promise<Card[]> {
|
||||
const docs = await this.collection.find({}, { projection: DOC_FIELDS }).toArray()
|
||||
return docs.map((doc) => this.mapDoc(doc))
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<Card | null> {
|
||||
const doc = await this.collection.findOne({ c_id: id }, { projection: DOC_FIELDS })
|
||||
return doc ? this.mapDoc(doc) : null
|
||||
}
|
||||
|
||||
async create(input: CardInput): Promise<Card> {
|
||||
const doc: CardDocument = {
|
||||
c_id: crypto.randomUUID(),
|
||||
question: input.question,
|
||||
response: input.response,
|
||||
theme: input.theme,
|
||||
tags: input.tags ?? [],
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
}
|
||||
await this.collection.insertOne(doc)
|
||||
return this.mapDoc(doc)
|
||||
}
|
||||
|
||||
async update(id: string, input: Partial<CardInput>): Promise<Card | null> {
|
||||
const set: Partial<CardDocument> = { updatedAt: new Date() }
|
||||
if (input.question !== undefined) {
|
||||
set.question = input.question
|
||||
}
|
||||
if (input.response !== undefined) {
|
||||
set.response = input.response
|
||||
}
|
||||
if (input.theme !== undefined) {
|
||||
set.theme = input.theme
|
||||
}
|
||||
if (input.tags !== undefined) {
|
||||
set.tags = input.tags
|
||||
}
|
||||
const result = await this.collection.updateOne({ c_id: id }, { $set: set })
|
||||
if (result.matchedCount === 0) {
|
||||
return null
|
||||
}
|
||||
return this.findById(id)
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<boolean> {
|
||||
const result = await this.collection.deleteOne({ c_id: id })
|
||||
return result.deletedCount > 0
|
||||
}
|
||||
|
||||
async findRandom(): Promise<Card | null> {
|
||||
const docs = await this.collection
|
||||
.aggregate<CardDocument>([{ $sample: { size: 1 } }, { $project: DOC_FIELDS }])
|
||||
.toArray()
|
||||
return docs[0] ? this.mapDoc(docs[0]) : null
|
||||
}
|
||||
|
||||
async findRandomByTheme(theme: string): Promise<Card | null> {
|
||||
const docs = await this.collection
|
||||
.aggregate<CardDocument>([
|
||||
{ $match: { theme } },
|
||||
{ $sample: { size: 1 } },
|
||||
{ $project: DOC_FIELDS },
|
||||
])
|
||||
.toArray()
|
||||
return docs[0] ? this.mapDoc(docs[0]) : null
|
||||
}
|
||||
|
||||
async findThemes(): Promise<string[]> {
|
||||
const themes: string[] = await this.collection.distinct('theme')
|
||||
return themes.sort()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user