feat(workspaces): implement Hub auto-cleanup and connection heartbeat

This commit is contained in:
mkorwel
2026-03-19 09:50:43 -07:00
parent c368e513b0
commit 5647fb09ae
7 changed files with 140 additions and 7 deletions
@@ -15,6 +15,7 @@ export interface WorkspaceData {
zone: string;
project_id: string;
created_at: string;
last_connected_at: string;
}
export interface WorkspaceRecord extends WorkspaceData {
@@ -28,9 +29,12 @@ export class WorkspaceService {
this.firestore = new Firestore();
}
private get collection() {
return this.firestore.collection('workspaces');
}
async listWorkspaces(ownerId: string): Promise<WorkspaceRecord[]> {
const snapshot = await this.firestore
.collection('workspaces')
const snapshot = await this.collection
.where('owner_id', '==', ownerId)
.get();
@@ -45,17 +49,21 @@ export class WorkspaceService {
}
async getWorkspace(id: string): Promise<WorkspaceRecord | null> {
const doc = await this.firestore.collection('workspaces').doc(id).get();
const doc = await this.collection.doc(id).get();
if (!doc.exists) return null;
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
return { id: doc.id, ...(doc.data() as WorkspaceData) };
}
async createWorkspace(id: string, data: WorkspaceData): Promise<void> {
await this.firestore.collection('workspaces').doc(id).set(data);
await this.collection.doc(id).set(data);
}
async updateWorkspace(id: string, data: Partial<WorkspaceData>): Promise<void> {
await this.collection.doc(id).update(data);
}
async deleteWorkspace(id: string): Promise<void> {
await this.firestore.collection('workspaces').doc(id).delete();
await this.collection.doc(id).delete();
}
}