|
1
|
import { |
|
2
|
repairGuides, |
|
3
|
troubleshootingFlows, |
|
4
|
deviceComponents, |
|
5
|
users, |
|
6
|
favorites, |
|
7
|
deviceBrands, |
|
8
|
deviceModels, |
|
9
|
guideCompatibility, |
|
10
|
type RepairGuide, |
|
11
|
type InsertRepairGuide, |
|
12
|
type TroubleshootingFlow, |
|
13
|
type InsertTroubleshootingFlow, |
|
14
|
type DeviceComponent, |
|
15
|
type InsertDeviceComponent, |
|
16
|
type User, |
|
17
|
type InsertUser, |
|
18
|
type Favorite, |
|
19
|
type InsertFavorite, |
|
20
|
type DeviceBrand, |
|
21
|
type InsertDeviceBrand, |
|
22
|
type DeviceModel, |
|
23
|
type InsertDeviceModel, |
|
24
|
type GuideCompatibility, |
|
25
|
type InsertGuideCompatibility, |
|
26
|
} from "@shared/schema"; |
|
27
|
import { db } from "./db"; |
|
28
|
import { eq, and, like, or, sql } from "drizzle-orm"; |
|
29
|
import bcrypt from "bcrypt"; |
|
30
|
import { comprehensiveRepairGuides, comprehensiveTroubleshootingFlows, comprehensiveDeviceComponents } from "./seed-data"; |
|
31
|
import { generateAllComprehensiveGuides } from "./seed-guides"; |
|
32
|
|
|
33
|
export interface IStorage { |
|
34
|
// User operations |
|
35
|
getUser(id: string): Promise<User | undefined>; |
|
36
|
getUserByEmail(email: string): Promise<User | undefined>; |
|
37
|
createUser(user: InsertUser): Promise<User>; |
|
38
|
updateUser(id: string, user: Partial<User>): Promise<User | undefined>; |
|
39
|
|
|
40
|
// Favorites operations |
|
41
|
getUserFavorites(userId: string): Promise<Favorite[]>; |
|
42
|
addToFavorites(userId: string, favorite: InsertFavorite): Promise<Favorite>; |
|
43
|
removeFromFavorites(userId: string, itemId: string, itemType: string): Promise<void>; |
|
44
|
isFavorited(userId: string, itemId: string, itemType: string): Promise<boolean>; |
|
45
|
|
|
46
|
// Repair Guides |
|
47
|
getRepairGuides(filters?: { deviceType?: string; category?: string; difficulty?: string }): Promise<RepairGuide[]>; |
|
48
|
getRepairGuide(id: string): Promise<RepairGuide | undefined>; |
|
49
|
createRepairGuide(guide: InsertRepairGuide): Promise<RepairGuide>; |
|
50
|
updateViewCount(id: string): Promise<void>; |
|
51
|
updateDownloadCount(id: string): Promise<void>; |
|
52
|
toggleBookmark(id: string): Promise<RepairGuide | undefined>; |
|
53
|
searchRepairGuides(query: string): Promise<RepairGuide[]>; |
|
54
|
|
|
55
|
// Troubleshooting Flows |
|
56
|
getTroubleshootingFlows(): Promise<TroubleshootingFlow[]>; |
|
57
|
getTroubleshootingFlow(id: string): Promise<TroubleshootingFlow | undefined>; |
|
58
|
createTroubleshootingFlow(flow: InsertTroubleshootingFlow): Promise<TroubleshootingFlow>; |
|
59
|
|
|
60
|
// Device Components |
|
61
|
getDeviceComponents(deviceType?: string): Promise<DeviceComponent[]>; |
|
62
|
getDeviceComponent(id: string): Promise<DeviceComponent | undefined>; |
|
63
|
createDeviceComponent(component: InsertDeviceComponent): Promise<DeviceComponent>; |
|
64
|
|
|
65
|
// Device Brands and Models |
|
66
|
getDeviceBrands(deviceType?: string): Promise<DeviceBrand[]>; |
|
67
|
getDeviceModels(brandId?: string, deviceType?: string): Promise<DeviceModel[]>; |
|
68
|
getDeviceModel(id: string): Promise<DeviceModel | undefined>; |
|
69
|
getModelsByBrand(brandId: string): Promise<DeviceModel[]>; |
|
70
|
searchDeviceModels(query: string, deviceType?: string): Promise<DeviceModel[]>; |
|
71
|
|
|
72
|
// Guide Compatibility |
|
73
|
getCompatibleGuides(modelId: string): Promise<RepairGuide[]>; |
|
74
|
getModelCompatibility(guideId: string): Promise<DeviceModel[]>; |
|
75
|
|
|
76
|
// User guide creation |
|
77
|
createUserGuide(guide: InsertRepairGuide): Promise<RepairGuide>; |
|
78
|
} |
|
79
|
|
|
80
|
export class DatabaseStorage implements IStorage { |
|
81
|
async getUser(id: string): Promise<User | undefined> { |
|
82
|
if (!db) return undefined; |
|
83
|
const [user] = await db.select().from(users).where(eq(users.id, id)); |
|
84
|
return user; |
|
85
|
} |
|
86
|
|
|
87
|
async getUserByEmail(email: string): Promise<User | undefined> { |
|
88
|
if (!db || !email) return undefined; |
|
89
|
const normalized = email.trim().toLowerCase(); |
|
90
|
const [user] = await db.select().from(users).where(sql`lower(${users.email}) = ${normalized}`); |
|
91
|
return user; |
|
92
|
} |
|
93
|
|
|
94
|
async createUser(userData: InsertUser): Promise<User> { |
|
95
|
if (!db) throw new Error("No database"); |
|
96
|
const [user] = await db.insert(users).values({ |
|
97
|
...userData, |
|
98
|
email: (userData.email || "").trim().toLowerCase() |
|
99
|
}).returning(); |
|
100
|
return user; |
|
101
|
} |
|
102
|
|
|
103
|
async updateUser(id: string, userData: Partial<User>): Promise<User | undefined> { |
|
104
|
if (!db) return undefined; |
|
105
|
const [user] = await db |
|
106
|
.update(users) |
|
107
|
.set({ ...userData, updatedAt: new Date() }) |
|
108
|
.where(eq(users.id, id)) |
|
109
|
.returning(); |
|
110
|
return user; |
|
111
|
} |
|
112
|
|
|
113
|
async getUserFavorites(userId: string): Promise<Favorite[]> { |
|
114
|
if (!db) return []; |
|
115
|
return await db.select().from(favorites).where(eq(favorites.userId, userId)); |
|
116
|
} |
|
117
|
|
|
118
|
async addToFavorites(userId: string, favorite: InsertFavorite): Promise<Favorite> { |
|
119
|
if (!db) throw new Error("No database"); |
|
120
|
const [newFavorite] = await db |
|
121
|
.insert(favorites) |
|
122
|
.values({ ...favorite, userId }) |
|
123
|
.returning(); |
|
124
|
return newFavorite; |
|
125
|
} |
|
126
|
|
|
127
|
async removeFromFavorites(userId: string, itemId: string, itemType: string): Promise<void> { |
|
128
|
if (!db) return; |
|
129
|
await db |
|
130
|
.delete(favorites) |
|
131
|
.where( |
|
132
|
and( |
|
133
|
eq(favorites.userId, userId), |
|
134
|
eq(favorites.itemId, itemId), |
|
135
|
eq(favorites.itemType, itemType) |
|
136
|
) |
|
137
|
); |
|
138
|
} |
|
139
|
|
|
140
|
async isFavorited(userId: string, itemId: string, itemType: string): Promise<boolean> { |
|
141
|
if (!db) return false; |
|
142
|
const [favorite] = await db |
|
143
|
.select() |
|
144
|
.from(favorites) |
|
145
|
.where( |
|
146
|
and( |
|
147
|
eq(favorites.userId, userId), |
|
148
|
eq(favorites.itemId, itemId), |
|
149
|
eq(favorites.itemType, itemType) |
|
150
|
) |
|
151
|
); |
|
152
|
return !!favorite; |
|
153
|
} |
|
154
|
|
|
155
|
async getRepairGuides(filters?: { deviceType?: string; category?: string; difficulty?: string }): Promise<RepairGuide[]> { |
|
156
|
if (!db) return []; |
|
157
|
const conditions = []; |
|
158
|
if (filters?.deviceType) { |
|
159
|
conditions.push(eq(repairGuides.deviceType, filters.deviceType)); |
|
160
|
} |
|
161
|
if (filters?.category) { |
|
162
|
conditions.push(eq(repairGuides.category, filters.category)); |
|
163
|
} |
|
164
|
if (filters?.difficulty) { |
|
165
|
conditions.push(eq(repairGuides.difficulty, filters.difficulty)); |
|
166
|
} |
|
167
|
|
|
168
|
if (conditions.length > 0) { |
|
169
|
return await db.select().from(repairGuides).where(and(...conditions)); |
|
170
|
} |
|
171
|
return await db.select().from(repairGuides); |
|
172
|
} |
|
173
|
|
|
174
|
async getRepairGuide(id: string): Promise<RepairGuide | undefined> { |
|
175
|
if (!db) return undefined; |
|
176
|
const [guide] = await db.select().from(repairGuides).where(eq(repairGuides.id, id)); |
|
177
|
return guide; |
|
178
|
} |
|
179
|
|
|
180
|
async createRepairGuide(guide: InsertRepairGuide): Promise<RepairGuide> { |
|
181
|
if (!db) throw new Error("No database"); |
|
182
|
const [newGuide] = await db.insert(repairGuides).values(guide).returning(); |
|
183
|
return newGuide; |
|
184
|
} |
|
185
|
|
|
186
|
async updateViewCount(id: string): Promise<void> { |
|
187
|
if (!db) return; |
|
188
|
await db |
|
189
|
.update(repairGuides) |
|
190
|
.set({ viewCount: sql`${repairGuides.viewCount} + 1` }) |
|
191
|
.where(eq(repairGuides.id, id)); |
|
192
|
} |
|
193
|
|
|
194
|
async updateDownloadCount(id: string): Promise<void> { |
|
195
|
if (!db) return; |
|
196
|
await db |
|
197
|
.update(repairGuides) |
|
198
|
.set({ downloadCount: sql`${repairGuides.downloadCount} + 1` }) |
|
199
|
.where(eq(repairGuides.id, id)); |
|
200
|
} |
|
201
|
|
|
202
|
async toggleBookmark(id: string): Promise<RepairGuide | undefined> { |
|
203
|
if (!db) return undefined; |
|
204
|
const [guide] = await db |
|
205
|
.update(repairGuides) |
|
206
|
.set({ isBookmarked: sql`NOT ${repairGuides.isBookmarked}` }) |
|
207
|
.where(eq(repairGuides.id, id)) |
|
208
|
.returning(); |
|
209
|
return guide; |
|
210
|
} |
|
211
|
|
|
212
|
async searchRepairGuides(query: string): Promise<RepairGuide[]> { |
|
213
|
if (!db) return []; |
|
214
|
const searchTerm = `%${query.toLowerCase()}%`; |
|
215
|
return await db |
|
216
|
.select() |
|
217
|
.from(repairGuides) |
|
218
|
.where( |
|
219
|
or( |
|
220
|
like(repairGuides.title, searchTerm), |
|
221
|
like(repairGuides.description, searchTerm), |
|
222
|
like(repairGuides.category, searchTerm) |
|
223
|
) |
|
224
|
); |
|
225
|
} |
|
226
|
|
|
227
|
async getTroubleshootingFlows(): Promise<TroubleshootingFlow[]> { |
|
228
|
if (!db) return []; |
|
229
|
return await db.select().from(troubleshootingFlows); |
|
230
|
} |
|
231
|
|
|
232
|
async getTroubleshootingFlow(id: string): Promise<TroubleshootingFlow | undefined> { |
|
233
|
if (!db) return undefined; |
|
234
|
const [flow] = await db.select().from(troubleshootingFlows).where(eq(troubleshootingFlows.id, id)); |
|
235
|
return flow; |
|
236
|
} |
|
237
|
|
|
238
|
async createTroubleshootingFlow(flow: InsertTroubleshootingFlow): Promise<TroubleshootingFlow> { |
|
239
|
if (!db) throw new Error("No database"); |
|
240
|
const [newFlow] = await db.insert(troubleshootingFlows).values(flow).returning(); |
|
241
|
return newFlow; |
|
242
|
} |
|
243
|
|
|
244
|
async getDeviceComponents(deviceType?: string): Promise<DeviceComponent[]> { |
|
245
|
if (!db) return []; |
|
246
|
if (deviceType) { |
|
247
|
return await db.select().from(deviceComponents).where(eq(deviceComponents.deviceType, deviceType)); |
|
248
|
} |
|
249
|
return await db.select().from(deviceComponents); |
|
250
|
} |
|
251
|
|
|
252
|
async getDeviceComponent(id: string): Promise<DeviceComponent | undefined> { |
|
253
|
if (!db) return undefined; |
|
254
|
const [component] = await db.select().from(deviceComponents).where(eq(deviceComponents.id, id)); |
|
255
|
return component; |
|
256
|
} |
|
257
|
|
|
258
|
async createDeviceComponent(component: InsertDeviceComponent): Promise<DeviceComponent> { |
|
259
|
if (!db) throw new Error("No database"); |
|
260
|
const [newComponent] = await db.insert(deviceComponents).values(component).returning(); |
|
261
|
return newComponent; |
|
262
|
} |
|
263
|
|
|
264
|
async getDeviceBrands(deviceType?: string): Promise<DeviceBrand[]> { |
|
265
|
if (!db) return []; |
|
266
|
const query = db.select().from(deviceBrands); |
|
267
|
if (deviceType) { |
|
268
|
return await query.where(eq(deviceBrands.deviceType, deviceType)).orderBy(sql`${deviceBrands.popularity} DESC`); |
|
269
|
} |
|
270
|
return await query.orderBy(sql`${deviceBrands.popularity} DESC`); |
|
271
|
} |
|
272
|
|
|
273
|
async getDeviceModels(brandId?: string, deviceType?: string): Promise<DeviceModel[]> { |
|
274
|
if (!db) return []; |
|
275
|
if (brandId) { |
|
276
|
return await db.select().from(deviceModels).where(eq(deviceModels.brandId, brandId)).orderBy(sql`${deviceModels.year} DESC, ${deviceModels.name} ASC`); |
|
277
|
} |
|
278
|
return await db.select().from(deviceModels).orderBy(sql`${deviceModels.year} DESC, ${deviceModels.name} ASC`); |
|
279
|
} |
|
280
|
|
|
281
|
async getDeviceModel(id: string): Promise<DeviceModel | undefined> { |
|
282
|
if (!db) return undefined; |
|
283
|
const [model] = await db.select().from(deviceModels).where(eq(deviceModels.id, id)); |
|
284
|
return model; |
|
285
|
} |
|
286
|
|
|
287
|
async getModelsByBrand(brandId: string): Promise<DeviceModel[]> { |
|
288
|
if (!db) return []; |
|
289
|
return await db.select() |
|
290
|
.from(deviceModels) |
|
291
|
.where(eq(deviceModels.brandId, brandId)) |
|
292
|
.orderBy(sql`${deviceModels.year} DESC, ${deviceModels.name} ASC`); |
|
293
|
} |
|
294
|
|
|
295
|
async searchDeviceModels(query: string, deviceType?: string): Promise<DeviceModel[]> { |
|
296
|
if (!db) return []; |
|
297
|
return await db.select() |
|
298
|
.from(deviceModels) |
|
299
|
.where( |
|
300
|
or( |
|
301
|
like(deviceModels.name, `%${query}%`), |
|
302
|
like(deviceModels.series, `%${query}%`) |
|
303
|
) |
|
304
|
) |
|
305
|
.orderBy(sql`${deviceModels.guideCount} DESC`); |
|
306
|
} |
|
307
|
|
|
308
|
async getCompatibleGuides(modelId: string): Promise<RepairGuide[]> { |
|
309
|
if (!db) return []; |
|
310
|
return await db.select() |
|
311
|
.from(repairGuides) |
|
312
|
.where(sql`id IN (SELECT guide_id FROM guide_compatibility WHERE model_id = ${modelId} AND compatibility = 'compatible')`) |
|
313
|
.orderBy(sql`${repairGuides.viewCount} DESC`); |
|
314
|
} |
|
315
|
|
|
316
|
async getModelCompatibility(guideId: string): Promise<DeviceModel[]> { |
|
317
|
if (!db) return []; |
|
318
|
return await db.select() |
|
319
|
.from(deviceModels) |
|
320
|
.where(sql`id IN (SELECT model_id FROM guide_compatibility WHERE guide_id = ${guideId})`) |
|
321
|
.orderBy(sql`${deviceModels.name} ASC`); |
|
322
|
} |
|
323
|
|
|
324
|
async createUserGuide(guide: InsertRepairGuide): Promise<RepairGuide> { |
|
325
|
if (!db) throw new Error("No database"); |
|
326
|
const [createdGuide] = await db |
|
327
|
.insert(repairGuides) |
|
328
|
.values(guide) |
|
329
|
.returning(); |
|
330
|
return createdGuide; |
|
331
|
} |
|
332
|
} |
|
333
|
|
|
334
|
export class MemStorage implements IStorage { |
|
335
|
private users: Map<string, User> = new Map(); |
|
336
|
private favorites: Map<string, Favorite> = new Map(); |
|
337
|
private repairGuides: Map<string, RepairGuide> = new Map(); |
|
338
|
private troubleshootingFlows: Map<string, TroubleshootingFlow> = new Map(); |
|
339
|
private deviceComponents: Map<string, DeviceComponent> = new Map(); |
|
340
|
private deviceBrands: Map<string, DeviceBrand> = new Map(); |
|
341
|
private deviceModels: Map<string, DeviceModel> = new Map(); |
|
342
|
private guideCompatibility: Map<string, GuideCompatibility> = new Map(); |
|
343
|
|
|
344
|
constructor() { |
|
345
|
this.seedInitialData(); |
|
346
|
} |
|
347
|
|
|
348
|
private seedInitialData() { |
|
349
|
// Seed comprehensive guides with start-to-finish intimate details |
|
350
|
const allGuides = generateAllComprehensiveGuides(); |
|
351
|
allGuides.forEach((g, index) => { |
|
352
|
const id = `guide-${index + 1}`; |
|
353
|
this.repairGuides.set(id, { |
|
354
|
id, |
|
355
|
title: g.title, |
|
356
|
description: g.description, |
|
357
|
deviceType: g.deviceType, |
|
358
|
category: g.category, |
|
359
|
difficulty: g.difficulty, |
|
360
|
estimatedTime: g.estimatedTime, |
|
361
|
toolsRequired: g.toolsRequired, |
|
362
|
safetyWarnings: g.safetyWarnings, |
|
363
|
steps: g.steps, |
|
364
|
alternativeSolutions: g.alternativeSolutions || null, |
|
365
|
imageUrl: g.imageUrl, |
|
366
|
viewCount: Math.floor(Math.random() * 800) + 50, |
|
367
|
downloadCount: Math.floor(Math.random() * 200) + 10, |
|
368
|
isBookmarked: false, |
|
369
|
}); |
|
370
|
}); |
|
371
|
|
|
372
|
// Seed troubleshooting flows |
|
373
|
comprehensiveTroubleshootingFlows.forEach((f: any, index) => { |
|
374
|
const id = `flow-${index + 1}`; |
|
375
|
const { category, ...flowData } = f; |
|
376
|
this.troubleshootingFlows.set(id, { |
|
377
|
id, |
|
378
|
type: category, |
|
379
|
title: flowData.title, |
|
380
|
description: flowData.description, |
|
381
|
steps: flowData.steps.map((step: any) => ({ |
|
382
|
id: `step-${step.stepNumber}`, |
|
383
|
question: step.description, |
|
384
|
answers: [{ |
|
385
|
text: step.solutions?.join(', ') || "Check solutions", |
|
386
|
nextStepId: step.stepNumber < flowData.steps.length ? `step-${step.stepNumber + 1}` : undefined |
|
387
|
}] |
|
388
|
})) |
|
389
|
}); |
|
390
|
}); |
|
391
|
|
|
392
|
// Seed device components |
|
393
|
comprehensiveDeviceComponents.forEach((c: any, index) => { |
|
394
|
const id = `comp-${index + 1}`; |
|
395
|
this.deviceComponents.set(id, { |
|
396
|
id, |
|
397
|
name: c.name, |
|
398
|
description: c.description, |
|
399
|
deviceType: c.deviceType, |
|
400
|
category: c.componentType, |
|
401
|
safetyNotes: c.commonIssues || [] |
|
402
|
}); |
|
403
|
}); |
|
404
|
|
|
405
|
// Seed Brands (Laptop & Desktop) |
|
406
|
const allBrands = [ |
|
407
|
// Laptop Brands |
|
408
|
{ id: "brand-apple-laptop", name: "Apple", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/apple", supportLevel: "official", popularity: 99 }, |
|
409
|
{ id: "brand-dell-laptop", name: "Dell", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/dell", supportLevel: "official", popularity: 96 }, |
|
410
|
{ id: "brand-lenovo-laptop", name: "Lenovo", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/lenovo", supportLevel: "official", popularity: 95 }, |
|
411
|
{ id: "brand-hp-laptop", name: "HP", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/hp", supportLevel: "official", popularity: 93 }, |
|
412
|
{ id: "brand-asus-laptop", name: "ASUS", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/asus", supportLevel: "official", popularity: 90 }, |
|
413
|
{ id: "brand-acer-laptop", name: "Acer", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/acer", supportLevel: "official", popularity: 84 }, |
|
414
|
{ id: "brand-msi-laptop", name: "MSI", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/msi", supportLevel: "official", popularity: 86 }, |
|
415
|
{ id: "brand-razer-laptop", name: "Razer", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/razer", supportLevel: "official", popularity: 87 }, |
|
416
|
{ id: "brand-microsoft-laptop", name: "Microsoft", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/microsoft", supportLevel: "official", popularity: 88 }, |
|
417
|
{ id: "brand-samsung-laptop", name: "Samsung", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/samsung", supportLevel: "official", popularity: 82 }, |
|
418
|
{ id: "brand-framework-laptop", name: "Framework", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/framework", supportLevel: "official", popularity: 85 }, |
|
419
|
{ id: "brand-lg-laptop", name: "LG", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/lg", supportLevel: "official", popularity: 78 }, |
|
420
|
{ id: "brand-gigabyte-laptop", name: "Gigabyte", deviceType: "laptop", logoUrl: "https://cdn.simpleicons.org/gigabyte", supportLevel: "community", popularity: 76 }, |
|
421
|
|
|
422
|
// Desktop Brands & Form Factors |
|
423
|
{ id: "brand-custom-desktop", name: "Custom Built PC", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/pcgamingwiki", supportLevel: "official", popularity: 100 }, |
|
424
|
{ id: "brand-apple-desktop", name: "Apple", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/apple", supportLevel: "official", popularity: 95 }, |
|
425
|
{ id: "brand-dell-desktop", name: "Dell", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/dell", supportLevel: "official", popularity: 94 }, |
|
426
|
{ id: "brand-hp-desktop", name: "HP", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/hp", supportLevel: "official", popularity: 91 }, |
|
427
|
{ id: "brand-lenovo-desktop", name: "Lenovo", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/lenovo", supportLevel: "official", popularity: 89 }, |
|
428
|
{ id: "brand-asus-desktop", name: "ASUS", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/asus", supportLevel: "official", popularity: 88 }, |
|
429
|
{ id: "brand-msi-desktop", name: "MSI", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/msi", supportLevel: "official", popularity: 85 }, |
|
430
|
{ id: "brand-corsair-desktop", name: "Corsair & NZXT", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/corsair", supportLevel: "official", popularity: 90 }, |
|
431
|
{ id: "brand-acer-desktop", name: "Acer", deviceType: "desktop", logoUrl: "https://cdn.simpleicons.org/acer", supportLevel: "community", popularity: 79 }, |
|
432
|
]; |
|
433
|
|
|
434
|
allBrands.forEach(b => { |
|
435
|
this.deviceBrands.set(b.id, { |
|
436
|
...b, |
|
437
|
createdAt: new Date() |
|
438
|
}); |
|
439
|
}); |
|
440
|
|
|
441
|
// Comprehensive Models across every major brand (70+ models) |
|
442
|
const allModels = [ |
|
443
|
// APPLE LAPTOPS |
|
444
|
{ id: "model-mbp-16-m3", brandId: "brand-apple-laptop", name: "MacBook Pro 16\" (M3 Pro / M3 Max)", series: "MacBook Pro", year: 2024, specifications: { cpu: "Apple M3 Max 16-Core", ram: "36GB-128GB Unified", storage: "512GB-8TB SSD", display: "16.2\" Liquid Retina XDR Mini-LED 120Hz" }, commonIssues: ["Display flex cable strain", "USB-C port wear", "Battery cycle depletion"], guideCount: 16 }, |
|
445
|
{ id: "model-mbp-14-m3", brandId: "brand-apple-laptop", name: "MacBook Pro 14\" (M3 / M3 Pro)", series: "MacBook Pro", year: 2023, specifications: { cpu: "Apple M3 Pro 12-Core", ram: "18GB-36GB Unified", storage: "512GB-4TB SSD", display: "14.2\" Liquid Retina XDR" }, commonIssues: ["Fan dust accumulation", "Trackpad haptic alignment", "MagSafe 3 port debris"], guideCount: 14 }, |
|
446
|
{ id: "model-mba-15-m3", brandId: "brand-apple-laptop", name: "MacBook Air 15\" (M3)", series: "MacBook Air", year: 2024, specifications: { cpu: "Apple M3 8-Core", ram: "16GB-24GB Unified", storage: "512GB SSD", display: "15.3\" Liquid Retina IPS" }, commonIssues: ["Passive thermal throttling under sustained load", "Keyboard keycap shine"], guideCount: 10 }, |
|
447
|
{ id: "model-mba-13-m2", brandId: "brand-apple-laptop", name: "MacBook Air 13\" (M2)", series: "MacBook Air", year: 2022, specifications: { cpu: "Apple M2 8-Core", ram: "8GB-16GB Unified", storage: "256GB-512GB SSD", display: "13.6\" Liquid Retina" }, commonIssues: ["Thermal pad modding", "Audio jack lint"], guideCount: 11 }, |
|
448
|
{ id: "model-mba-13-m1", brandId: "brand-apple-laptop", name: "MacBook Air 13\" (M1 Classic)", series: "MacBook Air", year: 2020, specifications: { cpu: "Apple M1 8-Core", ram: "8GB-16GB Unified", storage: "256GB-2TB SSD", display: "13.3\" Retina 2560x1600" }, commonIssues: ["Battery swelling", "Display flexgate repair", "Trackpad cable oxidation"], guideCount: 19 }, |
|
449
|
{ id: "model-mbp-13-intel", brandId: "brand-apple-laptop", name: "MacBook Pro 13\" (Intel Four Thunderbolt)", series: "MacBook Pro Legacy", year: 2020, specifications: { cpu: "Intel Core i5-1038NG7", ram: "16GB LPDDR4X", storage: "512GB SSD", display: "13.3\" Retina 2560x1600" }, commonIssues: ["Dual fan thermal paste degradation", "Butterfly/Magic keyboard replacement", "Battery swelling"], guideCount: 18 }, |
|
450
|
{ id: "model-mbp-15-retina", brandId: "brand-apple-laptop", name: "MacBook Pro 15\" Retina (Mid 2015 Legacy)", series: "MacBook Pro Legacy", year: 2015, specifications: { cpu: "Intel Core i7-4870HQ", ram: "16GB DDR3L", storage: "512GB Proprietary PCIe", display: "15.4\" Retina 2880x1800" }, commonIssues: ["Staingate anti-reflective coating delamination", "I/O board audio flex ribbon", "Battery pouch cell replacement"], guideCount: 22 }, |
|
451
|
|
|
452
|
// DELL LAPTOPS |
|
453
|
{ id: "model-dell-xps15-9530", brandId: "brand-dell-laptop", name: "XPS 15 9530", series: "XPS", year: 2023, specifications: { cpu: "Intel Core i7-13700H", ram: "32GB DDR5-4800 (Upgradeable)", storage: "1TB M.2 PCIe 4.0", display: "15.6\" 3.5K OLED Touch" }, commonIssues: ["Vapor chamber thermal paste drying", "Trackpad pre-travel rattle", "Battery health degradation"], guideCount: 19 }, |
|
454
|
{ id: "model-dell-xps13-plus", brandId: "brand-dell-laptop", name: "XPS 13 Plus 9320", series: "XPS", year: 2023, specifications: { cpu: "Intel Core i7-1360P", ram: "16GB LPDDR5", storage: "1TB NVMe", display: "13.4\" 4K UHD+ Touch" }, commonIssues: ["Capacitive function row responsiveness", "Zero-lattice keyboard ribbon seating"], guideCount: 12 }, |
|
455
|
{ id: "model-dell-xps16-9640", brandId: "brand-dell-laptop", name: "XPS 16 9640 (AI Series)", series: "XPS", year: 2024, specifications: { cpu: "Intel Core Ultra 9 185H", ram: "32GB-64GB LPDDR5x", storage: "2TB PCIe 4.0 NVMe", display: "16.3\" 4K+ OLED 90Hz" }, commonIssues: ["Seamless glass trackpad calibration", "Vapor chamber heatsink repaste", "Thunderbolt 4 port dock handshake"], guideCount: 15 }, |
|
456
|
{ id: "model-dell-lat-5440", brandId: "brand-dell-laptop", name: "Latitude 5440 Enterprise", series: "Latitude", year: 2024, specifications: { cpu: "Intel Core i5-1345U vPro", ram: "16GB DDR5 (2x SODIMM Slots)", storage: "512GB M.2 2230", display: "14.0\" FHD Non-Touch" }, commonIssues: ["SODIMM RAM upgrade", "M.2 2230 to 2280 bracket swap", "CMOS battery reset"], guideCount: 15 }, |
|
457
|
{ id: "model-dell-lat-7440", brandId: "brand-dell-laptop", name: "Latitude 7440 Ultralight", series: "Latitude", year: 2023, specifications: { cpu: "Intel Core i7-1365U vPro", ram: "16GB LPDDR5", storage: "512GB M.2 PCIe", display: "14.0\" 16:10 QHD+" }, commonIssues: ["Magnesium casing screw mounts", "Fingerprint reader daughterboard flex", "Wi-Fi 6E antenna clip"], guideCount: 14 }, |
|
458
|
{ id: "model-dell-prec-7780", brandId: "brand-dell-laptop", name: "Precision 7780 Mobile Workstation", series: "Precision Mobile", year: 2023, specifications: { cpu: "Intel Core i9-13950HX vPro", ram: "128GB CAMM / SODIMM DDR5", storage: "4x M.2 PCIe Gen4 NVMe (8TB)", gpu: "NVIDIA RTX 5000 Ada 16GB" }, commonIssues: ["CAMM memory module torque specs", "Vapor chamber thermal pad sizing", "SmartCard reader ribbon replacement"], guideCount: 21 }, |
|
459
|
{ id: "model-dell-alienware-m16", brandId: "brand-dell-laptop", name: "Alienware m16 R2 Gaming", series: "Alienware", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "32GB DDR5 5600MHz", storage: "2TB Dual NVMe", display: "16\" QHD+ 240Hz" }, commonIssues: ["Element 31 liquid metal paste migration", "High-RPM fan cleaning", "DC-in barrel jack repair"], guideCount: 22 }, |
|
460
|
{ id: "model-dell-alienware-x14", brandId: "brand-dell-laptop", name: "Alienware x14 R2 Ultra-Slim", series: "Alienware", year: 2023, specifications: { cpu: "Intel Core i7-13620H", ram: "32GB LPDDR5", storage: "1TB M.2 2280", display: "14.0\" QHD+ 165Hz" }, commonIssues: ["Dual pull fan debris removal", "Type-C 130W GaN charging negotiation", "RGB Stadium lighting strip repair"], guideCount: 13 }, |
|
461
|
{ id: "model-dell-insp-15", brandId: "brand-dell-laptop", name: "Inspiron 15 3520", series: "Inspiron", year: 2023, specifications: { cpu: "Intel Core i5-1235U", ram: "8GB-16GB DDR4", storage: "512GB NVMe", display: "15.6\" 120Hz IPS" }, commonIssues: ["Hinge mounting plastic standoff rupture", "Keyboard membrane replacement", "SATA HDD to SSD migration"], guideCount: 17 }, |
|
462
|
|
|
463
|
// LENOVO LAPTOPS |
|
464
|
{ id: "model-lenovo-x1-c11", brandId: "brand-lenovo-laptop", name: "ThinkPad X1 Carbon Gen 11", series: "ThinkPad", year: 2023, specifications: { cpu: "Intel Core i7-1365U vPro", ram: "32GB LPDDR5", storage: "1TB PCIe Gen4 NVMe", display: "14.0\" 2.8K OLED" }, commonIssues: ["Fan dust filter de-clogging", "TrackPoint cap & click buttons replacement", "Wi-Fi 6E antenna routing"], guideCount: 20 }, |
|
465
|
{ id: "model-lenovo-x1-c12", brandId: "brand-lenovo-laptop", name: "ThinkPad X1 Carbon Gen 12", series: "ThinkPad", year: 2024, specifications: { cpu: "Intel Core Ultra 7 165H", ram: "32GB-64GB LPDDR5x", storage: "2TB Gen4 NVMe", display: "14.0\" 2.8K OLED 120Hz" }, commonIssues: ["Communications bar webcam flex", "Haptic TouchPad click engine reset", "Dual outlet fan cleaning"], guideCount: 16 }, |
|
466
|
{ id: "model-lenovo-t14-g4", brandId: "brand-lenovo-laptop", name: "ThinkPad T14 Gen 4 (AMD / Intel)", series: "ThinkPad", year: 2023, specifications: { cpu: "AMD Ryzen 7 PRO 7840U", ram: "32GB LPDDR5x", storage: "1TB M.2 2280", display: "14.0\" WUXGA Low Power" }, commonIssues: ["Modular keyboard replacement", "Internal 52.5Wh battery swap", "RJ45 Ethernet drop-jaw repair"], guideCount: 21 }, |
|
467
|
{ id: "model-lenovo-p16-g2", brandId: "brand-lenovo-laptop", name: "ThinkPad P16 Gen 2 Workstation", series: "ThinkPad Workstation", year: 2023, specifications: { cpu: "Intel Core i9-13980HX", ram: "128GB DDR5 ECC (4x Slots)", storage: "Dual M.2 Gen4 NVMe", gpu: "RTX 5000 Ada" }, commonIssues: ["Vapor chamber liquid repaste", "4x SODIMM RAM slot sequencing", "SmartCard flex replacement"], guideCount: 24 }, |
|
468
|
{ id: "model-lenovo-legion-pro7", brandId: "brand-lenovo-laptop", name: "Legion Pro 7i Gen 9", series: "Legion", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "32GB DDR5 5600MHz", storage: "2TB Dual M.2 SSD", display: "16\" WQXGA 240Hz 500 nits" }, commonIssues: ["Coldfront 5.0 vapor chamber repaste", "RGB backlight controller firmware", "Dual fan de-dusting"], guideCount: 18 }, |
|
469
|
{ id: "model-lenovo-legion-slim5", brandId: "brand-lenovo-laptop", name: "Legion Slim 5 14\" OLED", series: "Legion Slim", year: 2024, specifications: { cpu: "AMD Ryzen 7 7840HS", ram: "32GB LPDDR5X", storage: "1TB M.2 2280", display: "14.5\" 2.8K 120Hz OLED" }, commonIssues: ["Vapor chamber phase-change pad installation", "Right-angle DC-in slim tip port check"], guideCount: 15 }, |
|
470
|
{ id: "model-lenovo-yoga-9i", brandId: "brand-lenovo-laptop", name: "Yoga 9i Dual-Screen / 2-in-1", series: "Yoga", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "16GB LPDDR5x", storage: "1TB Gen4 SSD", display: "Dual 13.3\" 2.8K OLED Touch" }, commonIssues: ["360-degree rotating soundbar hinge tension", "Active stylus digitizer calibration"], guideCount: 13 }, |
|
471
|
|
|
472
|
// HP LAPTOPS |
|
473
|
{ id: "model-hp-spectre-14", brandId: "brand-hp-laptop", name: "Spectre x360 14 (2024)", series: "Spectre", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "32GB LPDDR5x", storage: "2TB NVMe", display: "14.0\" 2.8K OLED Touch" }, commonIssues: ["Haptic trackpad calibration", "Bottom cover rubber foot adhesive", "USB-C PD handshake reset"], guideCount: 14 }, |
|
474
|
{ id: "model-hp-spectre-16", brandId: "brand-hp-laptop", name: "Spectre x360 16 OLED", series: "Spectre", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "32GB LPDDR5x", storage: "2TB NVMe", gpu: "RTX 4050 Laptop" }, commonIssues: ["360-degree gear hinge lubrication", "Dual blower fan cleaning", "OLED touch digitizer ribbon"], guideCount: 15 }, |
|
475
|
{ id: "model-hp-elitebook-840", brandId: "brand-hp-laptop", name: "EliteBook 840 G10", series: "EliteBook", year: 2023, specifications: { cpu: "Intel Core i7-1360P", ram: "32GB DDR5 (2x Slots)", storage: "1TB SSD", display: "14.0\" WUXGA Anti-Glare" }, commonIssues: ["Smart card reader flex cable", "RAM SODIMM capacity upgrade", "Sure View privacy filter troubleshooting"], guideCount: 16 }, |
|
476
|
{ id: "model-hp-zbook-fury16", brandId: "brand-hp-laptop", name: "ZBook Fury 16 G10 Mobile Workstation", series: "ZBook", year: 2023, specifications: { cpu: "Intel Core i9-13950HX", ram: "128GB DDR5 ECC (4x SODIMM)", storage: "4x M.2 NVMe SSDs (Up to 16TB)", gpu: "NVIDIA RTX 5000 Ada" }, commonIssues: ["Toolless chassis latch mechanism", "Quad M.2 thermal heatsink pad repaste", "BMS battery diagnostic"], guideCount: 22 }, |
|
477
|
{ id: "model-hp-omen-16", brandId: "brand-hp-laptop", name: "OMEN Transcend 16 Gaming", series: "OMEN", year: 2024, specifications: { cpu: "Intel Core i7-14700HX", ram: "32GB DDR5", storage: "1TB PCIe Gen4", display: "16.0\" Mini-LED 240Hz" }, commonIssues: ["Tempest Cooling fan shroud cleaning", "Hall-effect lid sensor alignment"], guideCount: 15 }, |
|
478
|
{ id: "model-hp-victus-16", brandId: "brand-hp-laptop", name: "Victus 16 Gaming Laptop", series: "Victus", year: 2023, specifications: { cpu: "AMD Ryzen 7 7840HS", ram: "16GB DDR5", storage: "1TB SSD", gpu: "RTX 4060" }, commonIssues: ["Screen hinge wobble tensioning", "Dual fan air intake foam swap", "DC power barrel socket replacement"], guideCount: 18 }, |
|
479
|
|
|
480
|
// ASUS LAPTOPS & HANDHELDS |
|
481
|
{ id: "model-asus-zephyrus-g14", brandId: "brand-asus-laptop", name: "ROG Zephyrus G14 (2024)", series: "ROG", year: 2024, specifications: { cpu: "AMD Ryzen 9 8945HS", ram: "32GB LPDDR5X", storage: "1TB M.2 NVMe", display: "14.0\" 3K OLED 120Hz G-SYNC" }, commonIssues: ["Liquid metal barrier inspection", "AniMe Matrix / Slash Lighting flex cable", "Fan bearing lubrication"], guideCount: 20 }, |
|
482
|
{ id: "model-asus-zephyrus-g16", brandId: "brand-asus-laptop", name: "ROG Zephyrus G16 (2024)", series: "ROG", year: 2024, specifications: { cpu: "Intel Core Ultra 9 185H", ram: "32GB LPDDR5x", storage: "2TB Dual NVMe", display: "16\" 2.5K OLED 240Hz" }, commonIssues: ["Tri-Fan cooling module de-dusting", "Vapor chamber repasting", "Type-C 100W PD charging controller"], guideCount: 19 }, |
|
483
|
{ id: "model-asus-strix-scar16", brandId: "brand-asus-laptop", name: "ROG Strix SCAR 16 (2024)", series: "ROG", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "64GB DDR5 5600MHz", storage: "2TB RAID 0 Gen4", display: "16.0\" QHD+ 240Hz Mini-LED" }, commonIssues: ["Tri-Fan cooling module cleaning", "Conductonaut Extreme liquid metal repaste", "Chassis RGB underglow strip swap"], guideCount: 17 }, |
|
484
|
{ id: "model-asus-zenbook-14", brandId: "brand-asus-laptop", name: "ZenBook 14 OLED UX3405", series: "ZenBook", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "16GB-32GB LPDDR5x", storage: "1TB Gen4 SSD", display: "14.0\" 3K 120Hz OLED" }, commonIssues: ["NumberPad virtual trackpad driver", "ErgoLift hinge friction adjustment"], guideCount: 11 }, |
|
485
|
{ id: "model-asus-rog-ally-x", brandId: "brand-asus-laptop", name: "ROG Ally X (Handheld Gaming PC)", series: "ROG Ally", year: 2024, specifications: { cpu: "AMD Ryzen Z1 Extreme", ram: "24GB LPDDR5X 7500MHz", storage: "1TB M.2 2280 Full-Size NVMe", battery: "80Wh High-Capacity" }, commonIssues: ["Hall-Effect joystick calibration & swap", "MicroSD slot thermal isolation tape", "Full-size 2280 M.2 SSD installation"], guideCount: 26 }, |
|
486
|
|
|
487
|
// ACER & MSI & RAZER & FRAMEWORK & OTHER LAPTOPS |
|
488
|
{ id: "model-acer-helios-16", brandId: "brand-acer-laptop", name: "Predator Helios 16", series: "Predator", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "32GB DDR5", storage: "2TB NVMe", display: "16\" WQXGA 240Hz IPS" }, commonIssues: ["AeroBlade 3D 5th Gen metal fan cleaning", "Liquid metal barrier reseal", "RGB swappable WASD keycaps"], guideCount: 18 }, |
|
489
|
{ id: "model-acer-swift-go14", brandId: "brand-acer-laptop", name: "Swift Go 14 OLED", series: "Swift", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "16GB LPDDR5X", storage: "1TB Gen4 SSD", display: "14.0\" 2.8K OLED 90Hz" }, commonIssues: ["TwinAir dual fan heatsink cleaning", "Secondary M.2 slot NVMe addition"], guideCount: 12 }, |
|
490
|
{ id: "model-msi-stealth-16", brandId: "brand-msi-laptop", name: "MSI Stealth 16 AI Studio", series: "Stealth", year: 2024, specifications: { cpu: "Intel Core Ultra 9 185H", ram: "32GB DDR5", storage: "2TB NVMe SSD", display: "16\" UHD+ 120Hz OLED" }, commonIssues: ["Cooler Boost 5 fan cleaning", "Inverted motherboard disassembly order", "Hinge anchor reinforcement"], guideCount: 15 }, |
|
491
|
{ id: "model-msi-titan-18", brandId: "brand-msi-laptop", name: "MSI Titan 18 HX Flagship", series: "Titan Flagship", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "128GB DDR5 (4x Slots)", storage: "1x PCIe Gen5 + 2x PCIe Gen4 SSDs", display: "18\" 4K 120Hz Mini-LED" }, commonIssues: ["Vapor chamber 3D cooling repaste", "Cherry MX mechanical keyboard switch swap", "Quad fan bearing service"], guideCount: 22 }, |
|
492
|
{ id: "model-razer-blade-16", brandId: "brand-razer-laptop", name: "Razer Blade 16 (Dual-Mode Display)", series: "Blade", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "32GB-64GB DDR5", storage: "2TB NVMe", display: "16\" Dual-Mode Mini-LED (4K 120Hz / FHD 240Hz)" }, commonIssues: ["Battery swelling prevention and replacement", "Vapor chamber repaste with PTM7950", "Synapse Chroma RGB controller reset"], guideCount: 23 }, |
|
493
|
{ id: "model-razer-blade-14", brandId: "brand-razer-laptop", name: "Razer Blade 14 (AMD)", series: "Blade", year: 2024, specifications: { cpu: "AMD Ryzen 9 8945HS", ram: "32GB-64GB DDR5 (2x Slots)", storage: "1TB PCIe 4.0", display: "14\" QHD+ 240Hz" }, commonIssues: ["Dual blower fan lint de-clogging", "M.2 SSD thermal pad replacement", "Trackpad click stiffness"], guideCount: 17 }, |
|
494
|
{ id: "model-framework-13", brandId: "brand-framework-laptop", name: "Framework Laptop 13 (Modular)", series: "Framework Modular", year: 2024, specifications: { cpu: "AMD Ryzen 7 7840U / Intel Core Ultra", ram: "Up to 64GB DDR5 SODIMM", storage: "Up to 4TB M.2 2280", display: "13.5\" 2256x1504 3:2" }, commonIssues: ["Expansion card USB-C slot swap", "Magnetic bezel replacement", "Battery RTC coin cell swap"], guideCount: 25 }, |
|
495
|
{ id: "model-framework-16", brandId: "brand-framework-laptop", name: "Framework Laptop 16 (Discrete GPU Bay)", series: "Framework Modular", year: 2024, specifications: { cpu: "AMD Ryzen 9 7940HS", ram: "64GB DDR5", storage: "2x M.2 (2280 + 2230)", gpu: "Modular Radeon RX 7700S Expansion Bay" }, commonIssues: ["Graphics Module interposer connector latching", "Hot-swappable keyboard and numpad deck re-seating", "Dual fan exhaust module swap"], guideCount: 28 }, |
|
496
|
{ id: "model-ms-surface-laptop5", brandId: "brand-microsoft-laptop", name: "Surface Laptop 5", series: "Surface", year: 2023, specifications: { cpu: "Intel Core i7-1265U", ram: "16GB LPDDR5x", storage: "512GB Removable SSD", display: "13.5\" PixelSense Touch" }, commonIssues: ["Magnetic keyboard fabric deck removal", "Removable M.2 2230 SSD upgrade", "Surface Connect port charging diagnostic"], guideCount: 14 }, |
|
497
|
{ id: "model-ms-surface-pro9", brandId: "brand-microsoft-laptop", name: "Surface Pro 9 / 10 2-in-1", series: "Surface Pro", year: 2023, specifications: { cpu: "Intel Core i7-1255U / SQ3 5G", ram: "16GB LPDDR5", storage: "256GB-1TB Removable 2230 SSD", display: "13.0\" PixelSense Flow 120Hz" }, commonIssues: ["Magnetic SSD hatch door removal", "Kickstand torque hinge adjustment", "Screen glass adhesive release"], guideCount: 19 }, |
|
498
|
{ id: "model-samsung-galaxy-book4", brandId: "brand-samsung-laptop", name: "Galaxy Book4 Ultra", series: "Galaxy Book", year: 2024, specifications: { cpu: "Intel Core Ultra 9 185H", ram: "32GB LPDDR5X", storage: "1TB Gen4 SSD", display: "16.0\" Dynamic AMOLED 2X Touch" }, commonIssues: ["Vapor chamber repasting", "Secondary M.2 slot NVMe expansion"], guideCount: 13 }, |
|
499
|
{ id: "model-lg-gram-17", brandId: "brand-lg-laptop", name: "LG Gram 17 (Ultra-Lightweight)", series: "Gram", year: 2024, specifications: { cpu: "Intel Core Ultra 7 155H", ram: "16GB-32GB LPDDR5x", storage: "1TB Dual M.2", display: "17.0\" WQXGA IPS Non-Glare" }, commonIssues: ["Magnesium chassis flex inspection", "Dual M.2 SSD installation", "Battery replacement"], guideCount: 12 }, |
|
500
|
{ id: "model-gigabyte-aorus-16x", brandId: "brand-gigabyte-laptop", name: "GIGABYTE AORUS 16X (2024)", series: "AORUS", year: 2024, specifications: { cpu: "Intel Core i9-14900HX", ram: "32GB DDR5 5600MHz", storage: "1TB + 1TB Dual Gen4", display: "16\" 165Hz WQXGA Panton-Validated" }, commonIssues: ["Windforce Infinity cooling overhaul", "RGB Beacon projection light repair", "Wi-Fi 7 BE200 module seating"], guideCount: 16 }, |
|
501
|
|
|
502
|
// ========================================== |
|
503
|
// DESKTOP MODELS & FORM FACTORS (30+ Desktop Models) |
|
504
|
// ========================================== |
|
505
|
{ id: "model-custom-atx-gaming", brandId: "brand-custom-desktop", name: "Standard Full/Mid ATX Gaming PC", series: "Custom PC", year: 2024, specifications: { cpu: "AMD Ryzen 7 7800X3D / Intel Core i7-14700K", ram: "32GB DDR5 6000MHz", storage: "2TB PCIe 4.0 NVMe", gpu: "NVIDIA GeForce RTX 4080 Super", psu: "850W ATX 3.0 Gold Modular" }, commonIssues: ["PCIe GPU reseating & 12VHPWR seating", "360mm AIO liquid cooler bleeding/pump whine", "RAM XMP/EXPO dual-channel profile stability", "Front panel header / ARGB wiring"], guideCount: 35 }, |
|
506
|
{ id: "model-custom-itx-sff", brandId: "brand-custom-desktop", name: "Mini-ITX Small Form Factor (SFF) Build", series: "Custom SFF", year: 2024, specifications: { cpu: "AMD Ryzen 7 7800X3D", ram: "32GB DDR5 Low-Profile", storage: "2TB M.2 Back-Mounted", gpu: "RTX 4070 Dual-Slot", psu: "SFX 750W Platinum" }, commonIssues: ["PCIe Gen4 riser cable bandwidth errors", "Tight cable routing around CPU cooler", "Small fan curve optimization"], guideCount: 28 }, |
|
507
|
{ id: "model-custom-watercooled", brandId: "brand-custom-desktop", name: "Custom Hardline Liquid Cooling Rig", series: "Custom Enthusiast", year: 2024, specifications: { cpu: "Intel Core i9-14900KS / AMD Ryzen 9 7950X3D", ram: "64GB DDR5 7200MHz", storage: "4TB PCIe Gen5 NVMe", gpu: "RTX 4090 Water Block", cooling: "Dual 360mm Radiators, D5 Pump" }, commonIssues: ["Loop drainage & distilled water flushing", "O-ring seal leak testing with air pressure tester", "Biocide and coolant dye fallout cleanup"], guideCount: 22 }, |
|
508
|
{ id: "model-custom-dual-chamber", brandId: "brand-custom-desktop", name: "Dual-Chamber Fishbowl Panoramic Glass PC", series: "Custom Aesthetic", year: 2024, specifications: { cpu: "Intel Core i9-14900K", ram: "64GB DDR5 RGB", storage: "4TB NVMe", gpu: "RTX 4090 Vertical Mount", fans: "9x Reverse-Blade 120mm PWM" }, commonIssues: ["Tempered glass panel standoff rubber washer check", "Reverse blade fan orientation airflow check", "12V-2x6 cable 90-degree adapter seating"], guideCount: 20 }, |
|
509
|
|
|
510
|
// APPLE DESKTOPS |
|
511
|
{ id: "model-mac-studio-m2", brandId: "brand-apple-desktop", name: "Mac Studio (M2 Max / M2 Ultra)", series: "Mac Studio", year: 2023, specifications: { cpu: "Apple M2 Ultra 24-Core CPU / 76-Core GPU", ram: "64GB-192GB Unified", storage: "1TB-8TB Proprietary SSD Modules", psu: "Internal 370W PSU" }, commonIssues: ["Dual blower fan dust removal", "Proprietary SSD module restoration via Apple Configurator", "Power supply replacement"], guideCount: 14 }, |
|
512
|
{ id: "model-mac-mini-m2", brandId: "brand-apple-desktop", name: "Mac mini (M2 / M2 Pro)", series: "Mac mini", year: 2023, specifications: { cpu: "Apple M2 Pro 12-Core", ram: "16GB-32GB Unified", storage: "512GB-2TB SSD" }, commonIssues: ["Antenna plate removal", "Internal fan replacement", "DC power supply board swap"], guideCount: 16 }, |
|
513
|
{ id: "model-imac-24-m3", brandId: "brand-apple-desktop", name: "iMac 24\" 4.5K Retina (M3)", series: "iMac", year: 2023, specifications: { cpu: "Apple M3 8-Core", ram: "16GB-24GB Unified", storage: "512GB-2TB SSD", display: "23.5\" 4.5K Retina 4480x2520" }, commonIssues: ["Display adhesive cutting wheel procedure", "Internal logic board swap", "Magnetic power cord socket cleaning"], guideCount: 12 }, |
|
514
|
{ id: "model-imac-27-intel", brandId: "brand-apple-desktop", name: "iMac 27\" 5K Retina (Intel Legacy)", series: "iMac Legacy", year: 2020, specifications: { cpu: "Intel Core i9-10910 10-Core", ram: "Up to 128GB DDR4 (User Door)", storage: "1TB-8TB SSD", gpu: "Radeon Pro 5700 XT 16GB" }, commonIssues: ["Blade SSD upgrade", "User RAM door 4-stick DDR4 installation", "Display hinge spring snap repair"], guideCount: 25 }, |
|
515
|
{ id: "model-mac-pro-tower", brandId: "brand-apple-desktop", name: "Mac Pro Tower (Apple Silicon / Intel)", series: "Mac Pro", year: 2023, specifications: { cpu: "Apple M2 Ultra / Intel Xeon W", ram: "Up to 1.5TB DDR4 ECC (Intel) / 192GB (M2)", storage: "Internal PCIe Storage", expansion: "7x PCIe Slots" }, commonIssues: ["PCIe card auxiliary power routing", "Stainless steel latch alignment", "MPX module reseating"], guideCount: 15 }, |
|
516
|
|
|
517
|
// DELL DESKTOPS |
|
518
|
{ id: "model-dell-optiplex-7010", brandId: "brand-dell-desktop", name: "OptiPlex 7010 / 7000 Micro Form Factor", series: "OptiPlex Micro", year: 2023, specifications: { cpu: "Intel Core i7-13700T", ram: "16GB-64GB DDR5 SODIMM", storage: "512GB M.2 2280 NVMe" }, commonIssues: ["Blower fan thermal paste refresh", "External 90W/130W Dell power brick testing", "SATA 2.5\" caddy cable replacement"], guideCount: 19 }, |
|
519
|
{ id: "model-dell-optiplex-5090-sff", brandId: "brand-dell-desktop", name: "OptiPlex 5090 / 7090 Small Form Factor (SFF)", series: "OptiPlex SFF", year: 2022, specifications: { cpu: "Intel Core i7-11700", ram: "32GB DDR4 (4x DIMM Slots)", storage: "1TB NVMe + 3.5\" HDD", psu: "Dell Proprietary 260W 80+ Platinum" }, commonIssues: ["Low-profile PCIe GPU installation (e.g. RTX 3050 6GB / GTX 1650)", "Proprietary 6-pin motherboard power supply swap", "CMOS CR2032 coin cell replacement"], guideCount: 24 }, |
|
520
|
{ id: "model-dell-optiplex-7000-tower", brandId: "brand-dell-desktop", name: "OptiPlex 7000 Full Tower", series: "OptiPlex Tower", year: 2023, specifications: { cpu: "Intel Core i7-13700", ram: "64GB DDR5", storage: "2TB NVMe + 4TB HDD", psu: "Dell 500W Platinum" }, commonIssues: ["PCIe graphics card bracket lock", "Front intake bezel dust cleaning", "SATA optical drive replacement"], guideCount: 17 }, |
|
521
|
{ id: "model-dell-alienware-r16", brandId: "brand-dell-desktop", name: "Alienware Aurora R16 Gaming Desktop", series: "Alienware Aurora", year: 2024, specifications: { cpu: "Intel Core i9-14900KF", ram: "32GB DDR5 5600MHz", storage: "2TB Gen4 SSD", gpu: "RTX 4080 Super 16GB", psu: "1000W 80+ Gold" }, commonIssues: ["240mm liquid cooler radiator cleaning", "GPU retention bracket removal", "12V-2x6 power cable routing"], guideCount: 20 }, |
|
522
|
{ id: "model-dell-precision-3660", brandId: "brand-dell-desktop", name: "Precision 3660 Tower Workstation", series: "Precision Workstation", year: 2023, specifications: { cpu: "Intel Core i9-13900K", ram: "64GB DDR5 ECC / Non-ECC", storage: "Dual 2TB PCIe Gen4 SSDs", gpu: "NVIDIA RTX A4000 / RTX 4080" }, commonIssues: ["Front air intake dust filter maintenance", "Secondary M.2 PCIe riser card setup", "ECC memory error detection"], guideCount: 21 }, |
|
523
|
|
|
524
|
// HP DESKTOPS |
|
525
|
{ id: "model-hp-omen-45l", brandId: "brand-hp-desktop", name: "OMEN 45L Gaming Desktop (Cryo-Chamber)", series: "OMEN Desktop", year: 2024, specifications: { cpu: "Intel Core i9-14900K", ram: "64GB Kingston FURY DDR5", storage: "2TB WD Black NVMe", cooling: "External Patented Cryo-Chamber 360mm AIO", psu: "1000W 80+ Gold" }, commonIssues: ["Cryo-Chamber radiator dust filter washing", "Standard ATX motherboard/GPU upgrades", "OMEN Gaming Hub RGB lighting sync"], guideCount: 22 }, |
|
526
|
{ id: "model-hp-omen-25l", brandId: "brand-hp-desktop", name: "OMEN 25L Mid-Tower Gaming", series: "OMEN Desktop", year: 2023, specifications: { cpu: "Intel Core i7-13700F", ram: "32GB HyperX DDR5", storage: "1TB SSD", gpu: "RTX 4070" }, commonIssues: ["Rear exhaust fan upgrade", "CPU air cooler tower replacement", "RAM XMP frequency enable in BIOS"], guideCount: 16 }, |
|
527
|
{ id: "model-hp-prodesk-600", brandId: "brand-hp-desktop", name: "ProDesk 600 G6 / G8 SFF", series: "ProDesk", year: 2022, specifications: { cpu: "Intel Core i5-11500", ram: "16GB DDR4", storage: "512GB M.2 SSD", psu: "HP 210W Active PFC" }, commonIssues: ["SFF power supply diagnostic", "Toolless drive bay unlatching", "BIOS admin password jumper clearing"], guideCount: 18 }, |
|
528
|
{ id: "model-hp-elitedesk-mini", brandId: "brand-hp-desktop", name: "EliteDesk 800 G8 / G9 Mini PC", series: "EliteDesk Mini", year: 2023, specifications: { cpu: "Intel Core i7-12700T", ram: "32GB DDR5", storage: "1TB M.2 Gen4" }, commonIssues: ["Flex IO v2 port module swapping (Type-C / DP / HDMI / 2.5GbE)", "Copper heatsink repaste", "Mini-PC fan acoustic balance"], guideCount: 17 }, |
|
529
|
{ id: "model-hp-z4-g5", brandId: "brand-hp-desktop", name: "HP Z4 G5 Workstation Tower", series: "Z Workstation", year: 2024, specifications: { cpu: "Intel Xeon w5-2465X", ram: "128GB DDR5 ECC Registered", storage: "Dual 4TB NVMe SSDs", psu: "1125W 90% Efficient" }, commonIssues: ["Hot-swappable front NVMe drive bays", "Memory cooling shroud latch", "Dual PCIe Gen5 GPU power distribution"], guideCount: 20 }, |
|
530
|
|
|
531
|
// LENOVO DESKTOPS |
|
532
|
{ id: "model-lenovo-m70q-tiny", brandId: "brand-lenovo-desktop", name: "ThinkCentre M70q / M90q Tiny PC", series: "ThinkCentre Tiny", year: 2023, specifications: { cpu: "Intel Core i7-13700T", ram: "16GB-64GB DDR5", storage: "512GB M.2 NVMe", dimensions: "1-Liter Compact Chassis" }, commonIssues: ["Toolless chassis thumbscrew removal", "Dust shield foam replacement", "Thermal paste refresh on direct-mount heatsink"], guideCount: 20 }, |
|
533
|
{ id: "model-lenovo-legion-t7", brandId: "brand-lenovo-desktop", name: "Legion Tower 7i Gen 8", series: "Legion Tower", year: 2024, specifications: { cpu: "Intel Core i9-13900KF", ram: "32GB DDR5 5600MHz", storage: "1TB + 1TB Dual SSD", gpu: "RTX 4080", psu: "850W Gold" }, commonIssues: ["ARGB 120mm fan hub diagnosis", "Legion Coldfront liquid cooler pump curve", "GPU anti-sag bracket mounting"], guideCount: 19 }, |
|
534
|
{ id: "model-lenovo-p360-ultra", brandId: "brand-lenovo-desktop", name: "ThinkStation P360 / P3 Ultra SFF Workstation", series: "ThinkStation", year: 2023, specifications: { cpu: "Intel Core i9-13900", ram: "128GB DDR5 SODIMM", storage: "2x M.2 PCIe Gen4", gpu: "NVIDIA RTX A5000 Mobile 16GB" }, commonIssues: ["Chassis pull-tab clamshell mechanism", "Dual blower fan cleaning", "External 300W high-power brick check"], guideCount: 21 }, |
|
535
|
|
|
536
|
// ASUS & MSI & CORSAIR & SPECIALIZED DESKTOPS |
|
537
|
{ id: "model-asus-rog-g16ch", brandId: "brand-asus-desktop", name: "ROG Strix G16CH Gaming Desktop", series: "ROG Strix", year: 2024, specifications: { cpu: "Intel Core i7-14700F", ram: "32GB DDR5", storage: "1TB M.2 Gen4", gpu: "RTX 4070 Super", psu: "700W 80+ Gold" }, commonIssues: ["Front mesh air intake cleaning", "Glass side panel thumbscrew rubber washer seating", "AURA Sync RGB lighting reset"], guideCount: 18 }, |
|
538
|
{ id: "model-asus-proart-pd5", brandId: "brand-asus-desktop", name: "ProArt Station PD5 Creator Desktop", series: "ProArt", year: 2023, specifications: { cpu: "Intel Core i9-13900", ram: "64GB DDR5", storage: "2TB Gen4 SSD", gpu: "NVIDIA RTX 4070 / RTX A4000" }, commonIssues: ["Lumiwiz LED status bar calibration", "Front I/O headphone latch replacement", "Hard drive hot-swap cage"], guideCount: 15 }, |
|
539
|
{ id: "model-corsair-one-i500", brandId: "brand-corsair-desktop", name: "Corsair ONE i500 Compact Luxury PC", series: "Corsair ONE", year: 2024, specifications: { cpu: "Intel Core i9-14900K", ram: "64GB DDR5", storage: "2TB Gen4 NVMe", cooling: "Dual Independent Closed-Loop Liquid Coolers", chassis: "FSC-certified Real Wood Front" }, commonIssues: ["Dual radiator side-panel dust blowing", "Underglow touch sensor recalibration", "SFX-L power supply cable check"], guideCount: 16 }, |
|
540
|
{ id: "model-msi-trident-x2", brandId: "brand-msi-desktop", name: "MSI MEG Trident X2 (HMI Touchscreen)", series: "MEG Trident", year: 2024, specifications: { cpu: "Intel Core i9-14900KF", ram: "64GB DDR5", storage: "2TB Gen5 + 2TB Gen4", gpu: "RTX 4090 24GB", psu: "1000W PCIe 5.0" }, commonIssues: ["Front 4.5\" HMI touchscreen firmware calibration", "Silent Storm Cooling 3 air chamber divider alignment"], guideCount: 17 }, |
|
541
|
{ id: "model-intel-nuc-13-extreme", brandId: "brand-corsair-desktop", name: "Intel NUC 13 Extreme (Raptor Canyon)", series: "Intel NUC", year: 2023, specifications: { cpu: "Intel Core i9-13900K Compute Element", ram: "64GB DDR5 SODIMM", storage: "3x M.2 PCIe 4.0 NVMe", gpu: "Triple-Slot 12\" PCIe GPU", psu: "750W SFX Gold" }, commonIssues: ["NUC Compute Element PCIe x16 daughterboard seating", "SFX power supply fan curve", "Triple M.2 heatsink plate pad repaste"], guideCount: 22 } |
|
542
|
]; |
|
543
|
|
|
544
|
allModels.forEach(m => { |
|
545
|
this.deviceModels.set(m.id, { |
|
546
|
...m, |
|
547
|
createdAt: new Date() |
|
548
|
}); |
|
549
|
}); |
|
550
|
|
|
551
|
// Compatibility mappings linking models to guides |
|
552
|
const guideKeys = Array.from(this.repairGuides.keys()); |
|
553
|
allModels.forEach((m) => { |
|
554
|
guideKeys.slice(0, 6).forEach((gId) => { |
|
555
|
const compatId = `compat-${m.id}-${gId}`; |
|
556
|
this.guideCompatibility.set(compatId, { |
|
557
|
id: compatId, |
|
558
|
guideId: gId, |
|
559
|
modelId: m.id, |
|
560
|
compatibility: "compatible", |
|
561
|
notes: "Fully verified compatibility with standard OEM repair procedures.", |
|
562
|
createdAt: new Date() |
|
563
|
}); |
|
564
|
}); |
|
565
|
}); |
|
566
|
|
|
567
|
// Seed master and default technician accounts |
|
568
|
try { |
|
569
|
const defaultPasswordHash = bcrypt.hashSync("password123", 10); |
|
570
|
const initialUsers: User[] = [ |
|
571
|
{ |
|
572
|
id: "user-master-tech", |
|
573
|
email: "jhustle44@gmail.com", |
|
574
|
password: defaultPasswordHash, |
|
575
|
firstName: "Master", |
|
576
|
lastName: "Technician", |
|
577
|
profileImageUrl: null, |
|
578
|
role: "admin", |
|
579
|
createdAt: new Date(), |
|
580
|
updatedAt: new Date(), |
|
581
|
}, |
|
582
|
{ |
|
583
|
id: "user-tech-lead", |
|
584
|
email: "tech@jcrguru.com", |
|
585
|
password: defaultPasswordHash, |
|
586
|
firstName: "Field", |
|
587
|
lastName: "Technician", |
|
588
|
profileImageUrl: null, |
|
589
|
role: "technician", |
|
590
|
createdAt: new Date(), |
|
591
|
updatedAt: new Date(), |
|
592
|
}, |
|
593
|
{ |
|
594
|
id: "user-admin-chief", |
|
595
|
email: "admin@jcrguru.com", |
|
596
|
password: defaultPasswordHash, |
|
597
|
firstName: "Workshop", |
|
598
|
lastName: "Admin", |
|
599
|
profileImageUrl: null, |
|
600
|
role: "admin", |
|
601
|
createdAt: new Date(), |
|
602
|
updatedAt: new Date(), |
|
603
|
}, |
|
604
|
{ |
|
605
|
id: "user-guest-demo", |
|
606
|
email: "demo@jcrguru.com", |
|
607
|
password: defaultPasswordHash, |
|
608
|
firstName: "Demo", |
|
609
|
lastName: "Technician", |
|
610
|
profileImageUrl: null, |
|
611
|
role: "user", |
|
612
|
createdAt: new Date(), |
|
613
|
updatedAt: new Date(), |
|
614
|
} |
|
615
|
]; |
|
616
|
|
|
617
|
initialUsers.forEach(u => { |
|
618
|
this.users.set(u.id, u); |
|
619
|
}); |
|
620
|
} catch (e) { |
|
621
|
console.warn("User seeding notice:", e); |
|
622
|
} |
|
623
|
} |
|
624
|
|
|
625
|
async getUser(id: string): Promise<User | undefined> { |
|
626
|
return this.users.get(id); |
|
627
|
} |
|
628
|
|
|
629
|
async getUserByEmail(email: string): Promise<User | undefined> { |
|
630
|
if (!email) return undefined; |
|
631
|
const target = email.trim().toLowerCase(); |
|
632
|
return Array.from(this.users.values()).find(u => u.email.toLowerCase() === target); |
|
633
|
} |
|
634
|
|
|
635
|
async createUser(user: InsertUser): Promise<User> { |
|
636
|
const id = `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; |
|
637
|
const newUser: User = { |
|
638
|
id, |
|
639
|
email: (user.email || "").trim().toLowerCase(), |
|
640
|
password: user.password, |
|
641
|
firstName: user.firstName || null, |
|
642
|
lastName: user.lastName || null, |
|
643
|
profileImageUrl: user.profileImageUrl || null, |
|
644
|
role: user.role || "user", |
|
645
|
createdAt: new Date(), |
|
646
|
updatedAt: new Date() |
|
647
|
}; |
|
648
|
this.users.set(id, newUser); |
|
649
|
return newUser; |
|
650
|
} |
|
651
|
|
|
652
|
async updateUser(id: string, user: Partial<User>): Promise<User | undefined> { |
|
653
|
const existing = this.users.get(id); |
|
654
|
if (!existing) return undefined; |
|
655
|
const updated = { ...existing, ...user, updatedAt: new Date() }; |
|
656
|
this.users.set(id, updated); |
|
657
|
return updated; |
|
658
|
} |
|
659
|
|
|
660
|
async getUserFavorites(userId: string): Promise<Favorite[]> { |
|
661
|
return Array.from(this.favorites.values()).filter(f => f.userId === userId); |
|
662
|
} |
|
663
|
|
|
664
|
async addToFavorites(userId: string, favorite: InsertFavorite): Promise<Favorite> { |
|
665
|
const id = `fav-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`; |
|
666
|
const newFav: Favorite = { |
|
667
|
id, |
|
668
|
userId, |
|
669
|
itemType: favorite.itemType, |
|
670
|
itemId: favorite.itemId, |
|
671
|
itemTitle: favorite.itemTitle, |
|
672
|
itemImageUrl: favorite.itemImageUrl || null, |
|
673
|
createdAt: new Date() |
|
674
|
}; |
|
675
|
this.favorites.set(id, newFav); |
|
676
|
return newFav; |
|
677
|
} |
|
678
|
|
|
679
|
async removeFromFavorites(userId: string, itemId: string, itemType: string): Promise<void> { |
|
680
|
for (const [id, f] of this.favorites.entries()) { |
|
681
|
if (f.userId === userId && f.itemId === itemId && f.itemType === itemType) { |
|
682
|
this.favorites.delete(id); |
|
683
|
} |
|
684
|
} |
|
685
|
} |
|
686
|
|
|
687
|
async isFavorited(userId: string, itemId: string, itemType: string): Promise<boolean> { |
|
688
|
return Array.from(this.favorites.values()).some( |
|
689
|
f => f.userId === userId && f.itemId === itemId && f.itemType === itemType |
|
690
|
); |
|
691
|
} |
|
692
|
|
|
693
|
async getRepairGuides(filters?: { deviceType?: string; category?: string; difficulty?: string }): Promise<RepairGuide[]> { |
|
694
|
let list = Array.from(this.repairGuides.values()); |
|
695
|
if (filters?.deviceType) { |
|
696
|
list = list.filter(g => g.deviceType === filters.deviceType); |
|
697
|
} |
|
698
|
if (filters?.category && filters.category !== "all") { |
|
699
|
list = list.filter(g => g.category === filters.category); |
|
700
|
} |
|
701
|
if (filters?.difficulty && filters.difficulty !== "all") { |
|
702
|
list = list.filter(g => g.difficulty === filters.difficulty); |
|
703
|
} |
|
704
|
return list; |
|
705
|
} |
|
706
|
|
|
707
|
async getRepairGuide(id: string): Promise<RepairGuide | undefined> { |
|
708
|
return this.repairGuides.get(id); |
|
709
|
} |
|
710
|
|
|
711
|
async createRepairGuide(guide: InsertRepairGuide): Promise<RepairGuide> { |
|
712
|
const id = `guide-${Date.now()}`; |
|
713
|
const newGuide: RepairGuide = { |
|
714
|
id, |
|
715
|
title: guide.title, |
|
716
|
description: guide.description, |
|
717
|
deviceType: guide.deviceType, |
|
718
|
category: guide.category, |
|
719
|
difficulty: guide.difficulty, |
|
720
|
estimatedTime: guide.estimatedTime, |
|
721
|
toolsRequired: guide.toolsRequired, |
|
722
|
safetyWarnings: guide.safetyWarnings, |
|
723
|
steps: guide.steps, |
|
724
|
alternativeSolutions: guide.alternativeSolutions || null, |
|
725
|
imageUrl: guide.imageUrl, |
|
726
|
viewCount: 0, |
|
727
|
downloadCount: 0, |
|
728
|
isBookmarked: false, |
|
729
|
}; |
|
730
|
this.repairGuides.set(id, newGuide); |
|
731
|
return newGuide; |
|
732
|
} |
|
733
|
|
|
734
|
async updateViewCount(id: string): Promise<void> { |
|
735
|
const guide = this.repairGuides.get(id); |
|
736
|
if (guide) { |
|
737
|
guide.viewCount = (guide.viewCount || 0) + 1; |
|
738
|
} |
|
739
|
} |
|
740
|
|
|
741
|
async updateDownloadCount(id: string): Promise<void> { |
|
742
|
const guide = this.repairGuides.get(id); |
|
743
|
if (guide) { |
|
744
|
guide.downloadCount = (guide.downloadCount || 0) + 1; |
|
745
|
} |
|
746
|
} |
|
747
|
|
|
748
|
async toggleBookmark(id: string): Promise<RepairGuide | undefined> { |
|
749
|
const guide = this.repairGuides.get(id); |
|
750
|
if (guide) { |
|
751
|
guide.isBookmarked = !guide.isBookmarked; |
|
752
|
return guide; |
|
753
|
} |
|
754
|
return undefined; |
|
755
|
} |
|
756
|
|
|
757
|
async searchRepairGuides(query: string): Promise<RepairGuide[]> { |
|
758
|
const q = query.trim().toLowerCase(); |
|
759
|
if (!q) return Array.from(this.repairGuides.values()); |
|
760
|
return Array.from(this.repairGuides.values()).filter(g => { |
|
761
|
const matchTitle = g.title.toLowerCase().includes(q); |
|
762
|
const matchDesc = g.description.toLowerCase().includes(q); |
|
763
|
const matchCategory = g.category.toLowerCase().includes(q); |
|
764
|
const matchDevice = g.deviceType.toLowerCase().includes(q); |
|
765
|
const matchDifficulty = g.difficulty.toLowerCase().includes(q); |
|
766
|
const matchTools = g.toolsRequired && g.toolsRequired.some(t => t.toLowerCase().includes(q)); |
|
767
|
const matchSteps = g.steps && g.steps.some(s => s.title.toLowerCase().includes(q) || s.description.toLowerCase().includes(q)); |
|
768
|
return matchTitle || matchDesc || matchCategory || matchDevice || matchDifficulty || matchTools || matchSteps; |
|
769
|
}); |
|
770
|
} |
|
771
|
|
|
772
|
async getTroubleshootingFlows(): Promise<TroubleshootingFlow[]> { |
|
773
|
return Array.from(this.troubleshootingFlows.values()); |
|
774
|
} |
|
775
|
|
|
776
|
async getTroubleshootingFlow(id: string): Promise<TroubleshootingFlow | undefined> { |
|
777
|
return this.troubleshootingFlows.get(id); |
|
778
|
} |
|
779
|
|
|
780
|
async createTroubleshootingFlow(flow: InsertTroubleshootingFlow): Promise<TroubleshootingFlow> { |
|
781
|
const id = `flow-${Date.now()}`; |
|
782
|
const newFlow: TroubleshootingFlow = { |
|
783
|
id, |
|
784
|
type: flow.type, |
|
785
|
title: flow.title, |
|
786
|
description: flow.description, |
|
787
|
steps: flow.steps, |
|
788
|
}; |
|
789
|
this.troubleshootingFlows.set(id, newFlow); |
|
790
|
return newFlow; |
|
791
|
} |
|
792
|
|
|
793
|
async getDeviceComponents(deviceType?: string): Promise<DeviceComponent[]> { |
|
794
|
let list = Array.from(this.deviceComponents.values()); |
|
795
|
if (deviceType) { |
|
796
|
list = list.filter(c => c.deviceType === deviceType); |
|
797
|
} |
|
798
|
return list; |
|
799
|
} |
|
800
|
|
|
801
|
async getDeviceComponent(id: string): Promise<DeviceComponent | undefined> { |
|
802
|
return this.deviceComponents.get(id); |
|
803
|
} |
|
804
|
|
|
805
|
async createDeviceComponent(component: InsertDeviceComponent): Promise<DeviceComponent> { |
|
806
|
const id = `comp-${Date.now()}`; |
|
807
|
const newComp: DeviceComponent = { |
|
808
|
id, |
|
809
|
name: component.name, |
|
810
|
description: component.description, |
|
811
|
deviceType: component.deviceType, |
|
812
|
category: component.category, |
|
813
|
safetyNotes: component.safetyNotes, |
|
814
|
}; |
|
815
|
this.deviceComponents.set(id, newComp); |
|
816
|
return newComp; |
|
817
|
} |
|
818
|
|
|
819
|
async getDeviceBrands(deviceType?: string): Promise<DeviceBrand[]> { |
|
820
|
let list = Array.from(this.deviceBrands.values()); |
|
821
|
if (deviceType) { |
|
822
|
list = list.filter(b => b.deviceType === deviceType); |
|
823
|
} |
|
824
|
return list.sort((a, b) => (b.popularity || 0) - (a.popularity || 0)); |
|
825
|
} |
|
826
|
|
|
827
|
async getDeviceModels(brandId?: string, deviceType?: string): Promise<DeviceModel[]> { |
|
828
|
let list = Array.from(this.deviceModels.values()); |
|
829
|
if (brandId) { |
|
830
|
list = list.filter(m => m.brandId === brandId); |
|
831
|
} |
|
832
|
return list.sort((a, b) => (b.year || 0) - (a.year || 0)); |
|
833
|
} |
|
834
|
|
|
835
|
async getDeviceModel(id: string): Promise<DeviceModel | undefined> { |
|
836
|
return this.deviceModels.get(id); |
|
837
|
} |
|
838
|
|
|
839
|
async getModelsByBrand(brandId: string): Promise<DeviceModel[]> { |
|
840
|
return Array.from(this.deviceModels.values()) |
|
841
|
.filter(m => m.brandId === brandId) |
|
842
|
.sort((a, b) => (b.year || 0) - (a.year || 0)); |
|
843
|
} |
|
844
|
|
|
845
|
async searchDeviceModels(query: string, deviceType?: string): Promise<DeviceModel[]> { |
|
846
|
const q = query.trim().toLowerCase(); |
|
847
|
let list = Array.from(this.deviceModels.values()); |
|
848
|
if (deviceType) { |
|
849
|
const matchingBrandIds = new Set( |
|
850
|
Array.from(this.deviceBrands.values()) |
|
851
|
.filter(b => b.deviceType === deviceType) |
|
852
|
.map(b => b.id) |
|
853
|
); |
|
854
|
list = list.filter(m => matchingBrandIds.has(m.brandId)); |
|
855
|
} |
|
856
|
if (!q) return list; |
|
857
|
|
|
858
|
return list.filter(m => { |
|
859
|
const matchName = m.name.toLowerCase().includes(q); |
|
860
|
const matchSeries = m.series ? m.series.toLowerCase().includes(q) : false; |
|
861
|
const matchYear = m.year ? m.year.toString().includes(q) : false; |
|
862
|
const matchSpecs = m.specifications ? JSON.stringify(m.specifications).toLowerCase().includes(q) : false; |
|
863
|
const matchIssues = m.commonIssues ? JSON.stringify(m.commonIssues).toLowerCase().includes(q) : false; |
|
864
|
return matchName || matchSeries || matchYear || matchSpecs || matchIssues; |
|
865
|
}); |
|
866
|
} |
|
867
|
|
|
868
|
async getCompatibleGuides(modelId: string): Promise<RepairGuide[]> { |
|
869
|
const matchingCompats = Array.from(this.guideCompatibility.values()).filter( |
|
870
|
c => c.modelId === modelId && c.compatibility === "compatible" |
|
871
|
); |
|
872
|
const guideIds = new Set(matchingCompats.map(c => c.guideId)); |
|
873
|
return Array.from(this.repairGuides.values()).filter(g => guideIds.has(g.id)); |
|
874
|
} |
|
875
|
|
|
876
|
async getModelCompatibility(guideId: string): Promise<DeviceModel[]> { |
|
877
|
const matchingCompats = Array.from(this.guideCompatibility.values()).filter( |
|
878
|
c => c.guideId === guideId |
|
879
|
); |
|
880
|
const modelIds = new Set(matchingCompats.map(c => c.modelId)); |
|
881
|
return Array.from(this.deviceModels.values()).filter(m => modelIds.has(m.id)); |
|
882
|
} |
|
883
|
|
|
884
|
async createUserGuide(guide: InsertRepairGuide): Promise<RepairGuide> { |
|
885
|
return this.createRepairGuide(guide); |
|
886
|
} |
|
887
|
} |
|
888
|
|
|
889
|
export const storage = db ? new DatabaseStorage() : new MemStorage(); |