VIBN Frontend for Coolify deployment
This commit is contained in:
64
lib/server/projects.ts
Normal file
64
lib/server/projects.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { FieldValue } from 'firebase-admin/firestore';
|
||||
import { getAdminDb } from '@/lib/firebase/admin';
|
||||
import type {
|
||||
ProjectPhase,
|
||||
ProjectPhaseData,
|
||||
ProjectPhaseScores,
|
||||
ProjectStage,
|
||||
} from '@/lib/types/project-artifacts';
|
||||
|
||||
export const clamp = (value: number) => Math.max(0, Math.min(1, value));
|
||||
export const nowIso = () => new Date().toISOString();
|
||||
|
||||
export function uniqueStrings(values: Array<string | null | undefined>): string[] {
|
||||
return Array.from(new Set(values.filter((value): value is string => Boolean(value))));
|
||||
}
|
||||
|
||||
export function toStage(stage?: string | null): ProjectStage {
|
||||
const allowed: ProjectStage[] = ['idea', 'prototype', 'mvp_in_progress', 'live_beta', 'live_paid', 'unknown'];
|
||||
if (!stage) return 'unknown';
|
||||
return allowed.includes(stage as ProjectStage) ? (stage as ProjectStage) : 'unknown';
|
||||
}
|
||||
|
||||
export async function loadPhaseContainers(projectId: string) {
|
||||
const adminDb = getAdminDb();
|
||||
const projectRef = adminDb.collection('projects').doc(projectId);
|
||||
const snapshot = await projectRef.get();
|
||||
const doc = snapshot.data() || {};
|
||||
const phaseData = (doc.phaseData ?? {}) as ProjectPhaseData;
|
||||
const phaseScores = (doc.phaseScores ?? {}) as ProjectPhaseScores;
|
||||
const phaseHistory = Array.isArray(doc.phaseHistory) ? [...doc.phaseHistory] : [];
|
||||
return { projectRef, phaseData, phaseScores, phaseHistory };
|
||||
}
|
||||
|
||||
interface PersistencePayload {
|
||||
phaseData: ProjectPhaseData;
|
||||
phaseScores: ProjectPhaseScores;
|
||||
phaseHistory: Array<Record<string, unknown>>;
|
||||
nextPhase?: ProjectPhase;
|
||||
}
|
||||
|
||||
export async function persistPhaseArtifacts(
|
||||
projectId: string,
|
||||
builder: (
|
||||
phaseData: ProjectPhaseData,
|
||||
phaseScores: ProjectPhaseScores,
|
||||
phaseHistory: Array<Record<string, unknown>>,
|
||||
) => PersistencePayload,
|
||||
) {
|
||||
const { projectRef, phaseData, phaseScores, phaseHistory } = await loadPhaseContainers(projectId);
|
||||
const payload = builder(phaseData, phaseScores, phaseHistory);
|
||||
|
||||
await projectRef.set(
|
||||
{
|
||||
phaseData: payload.phaseData,
|
||||
phaseScores: payload.phaseScores,
|
||||
phaseHistory: payload.phaseHistory,
|
||||
...(payload.nextPhase ? { currentPhase: payload.nextPhase, phaseStatus: 'completed' as const } : {}),
|
||||
updatedAt: FieldValue.serverTimestamp(),
|
||||
},
|
||||
{ merge: true },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user