Initial implementation of Bluetooth toy control app
Next.js app with a browser-side buttplug/buttplug-wasm control layer (server never touches real-time device commands), SQLite storage via Drizzle, single-secret auth, recordings/replay with device remapping, a usage stats dashboard, Docker deployment, and Gitea CI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "@/lib/db/client";
|
||||
import { devices, type DeviceCapabilities } from "@/lib/db/schema";
|
||||
|
||||
export async function listDevices() {
|
||||
return db.select().from(devices).orderBy(devices.lastConnectedAt);
|
||||
}
|
||||
|
||||
export async function getDevice(id: number) {
|
||||
const [row] = await db.select().from(devices).where(eq(devices.id, id));
|
||||
return row;
|
||||
}
|
||||
|
||||
/** Upserts by advertised BLE name - the only stable-ish identity Web Bluetooth exposes. */
|
||||
export async function upsertDeviceByBleName(input: {
|
||||
bleName: string;
|
||||
deviceClass?: string | null;
|
||||
capabilities?: DeviceCapabilities;
|
||||
}): Promise<typeof devices.$inferSelect> {
|
||||
const now = Date.now();
|
||||
const [existing] = await db.select().from(devices).where(eq(devices.bleName, input.bleName));
|
||||
|
||||
if (existing) {
|
||||
const [updated] = await db
|
||||
.update(devices)
|
||||
.set({
|
||||
lastConnectedAt: now,
|
||||
deviceClass: input.deviceClass ?? existing.deviceClass,
|
||||
capabilities: input.capabilities ?? existing.capabilities,
|
||||
})
|
||||
.where(eq(devices.id, existing.id))
|
||||
.returning();
|
||||
return updated;
|
||||
}
|
||||
|
||||
const [created] = await db
|
||||
.insert(devices)
|
||||
.values({
|
||||
bleName: input.bleName,
|
||||
deviceClass: input.deviceClass,
|
||||
capabilities: input.capabilities,
|
||||
createdAt: now,
|
||||
lastConnectedAt: now,
|
||||
})
|
||||
.returning();
|
||||
return created;
|
||||
}
|
||||
|
||||
export async function renameDevice(id: number, displayName: string) {
|
||||
const [updated] = await db.update(devices).set({ displayName }).where(eq(devices.id, id)).returning();
|
||||
return updated;
|
||||
}
|
||||
Reference in New Issue
Block a user