feat(backend): migrate freelancer and portal runtimes
This commit is contained in:
@@ -1,106 +1,48 @@
|
||||
"use server";
|
||||
|
||||
import { createClient } from "@/lib/supabase/server";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { cleanText, requiredText } from "@/server/web/form-data";
|
||||
import { requireFreelancerBackend } from "@/server/web/freelancer";
|
||||
|
||||
function cleanText(value: FormDataEntryValue | null) {
|
||||
const text = typeof value === "string" ? value.trim() : "";
|
||||
return text.length > 0 ? text : null;
|
||||
function score(value: FormDataEntryValue | null): number | null {
|
||||
const parsed = Number(value);
|
||||
return Number.isInteger(parsed) && parsed >= 1 && parsed <= 5 ? parsed : null;
|
||||
}
|
||||
|
||||
function readScore(value: FormDataEntryValue | null) {
|
||||
const score = Number(typeof value === "string" ? value : value?.toString());
|
||||
return Number.isInteger(score) && score >= 1 && score <= 5 ? score : null;
|
||||
}
|
||||
|
||||
async function getCurrentUserId() {
|
||||
const supabase = await createClient();
|
||||
const {
|
||||
data: { user },
|
||||
error,
|
||||
} = await supabase.auth.getUser();
|
||||
|
||||
if (error || !user) {
|
||||
throw new Error("Günlük kaydı için giriş yapmış kullanıcı bulunamadı.");
|
||||
}
|
||||
|
||||
return { supabase, userId: user.id };
|
||||
}
|
||||
|
||||
function readPayload(formData: FormData) {
|
||||
function payload(formData: FormData) {
|
||||
const moodScore = score(formData.get("mood_score"));
|
||||
const energyScore = score(formData.get("energy_score"));
|
||||
if (!moodScore || !energyScore) throw new Error("Mood ve enerji skorları zorunludur.");
|
||||
return {
|
||||
log_date: cleanText(formData.get("log_date")) || new Date().toISOString().slice(0, 10),
|
||||
mood_score: readScore(formData.get("mood_score")),
|
||||
energy_score: readScore(formData.get("energy_score")),
|
||||
work_satisfaction_score: readScore(formData.get("work_satisfaction_score")),
|
||||
entryDate: cleanText(formData.get("log_date")) ?? new Date().toISOString().slice(0, 10),
|
||||
moodScore,
|
||||
energyScore,
|
||||
workSatisfactionScore: score(formData.get("work_satisfaction_score")),
|
||||
note: cleanText(formData.get("note")),
|
||||
};
|
||||
}
|
||||
|
||||
export async function createDailyLogRecord(formData: FormData) {
|
||||
const { supabase, userId } = await getCurrentUserId();
|
||||
const payload = readPayload(formData);
|
||||
|
||||
if (!payload.mood_score || !payload.energy_score) {
|
||||
throw new Error("Mood ve enerji skorları zorunludur.");
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from("daily_logs")
|
||||
.upsert(
|
||||
{
|
||||
user_id: userId,
|
||||
...payload,
|
||||
},
|
||||
{ onConflict: "user_id,log_date" },
|
||||
);
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Günlük kaydı eklenemedi: ${error.message}`);
|
||||
}
|
||||
|
||||
const { actor, service } = await requireFreelancerBackend();
|
||||
service.saveJournalEntry(actor, payload(formData));
|
||||
revalidatePath("/journal");
|
||||
}
|
||||
|
||||
export async function updateDailyLogRecord(formData: FormData) {
|
||||
const { supabase, userId } = await getCurrentUserId();
|
||||
const id = cleanText(formData.get("id"));
|
||||
const payload = readPayload(formData);
|
||||
|
||||
if (!id || !payload.mood_score || !payload.energy_score) {
|
||||
throw new Error("Günlük kaydını güncellemek için kayıt kimliği, mood ve enerji skorları zorunludur.");
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from("daily_logs")
|
||||
.update(payload)
|
||||
.eq("id", id)
|
||||
.eq("user_id", userId);
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Günlük kaydı güncellenemedi: ${error.message}`);
|
||||
}
|
||||
|
||||
const { actor, service } = await requireFreelancerBackend();
|
||||
service.updateJournalEntry(
|
||||
actor,
|
||||
requiredText(formData.get("id"), "Günlük kaydı bulunamadı."),
|
||||
payload(formData),
|
||||
);
|
||||
revalidatePath("/journal");
|
||||
}
|
||||
|
||||
export async function deleteDailyLogRecord(formData: FormData) {
|
||||
const { supabase, userId } = await getCurrentUserId();
|
||||
const id = cleanText(formData.get("id"));
|
||||
|
||||
if (!id) {
|
||||
throw new Error("Silinecek günlük kaydı bulunamadı.");
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from("daily_logs")
|
||||
.delete()
|
||||
.eq("id", id)
|
||||
.eq("user_id", userId);
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Günlük kaydı silinemedi: ${error.message}`);
|
||||
}
|
||||
|
||||
const { actor, service } = await requireFreelancerBackend();
|
||||
service.deleteJournalEntry(
|
||||
actor,
|
||||
requiredText(formData.get("id"), "Silinecek günlük kaydı bulunamadı."),
|
||||
);
|
||||
revalidatePath("/journal");
|
||||
}
|
||||
|
||||
@@ -1,41 +1,22 @@
|
||||
import { JournalClient, type DailyLogItem } from "@/app/(dashboard)/journal/journal-client";
|
||||
import { createClient } from "@/lib/supabase/server";
|
||||
|
||||
type DailyLogRow = {
|
||||
id: string;
|
||||
log_date: string;
|
||||
mood_score: number;
|
||||
energy_score: number;
|
||||
work_satisfaction_score: number | null;
|
||||
note: string | null;
|
||||
};
|
||||
import { requireFreelancerBackend } from "@/server/web/freelancer";
|
||||
|
||||
export default async function JournalPage() {
|
||||
const supabase = await createClient();
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data: logRows } = await supabase
|
||||
.from("daily_logs")
|
||||
.select("id, log_date, mood_score, energy_score, work_satisfaction_score, note")
|
||||
.eq("user_id", user.id)
|
||||
.order("log_date", { ascending: false })
|
||||
.limit(180);
|
||||
|
||||
const logs: DailyLogItem[] = ((logRows || []) as DailyLogRow[]).map((log) => ({
|
||||
id: log.id,
|
||||
log_date: log.log_date,
|
||||
mood_score: Number(log.mood_score),
|
||||
energy_score: Number(log.energy_score),
|
||||
work_satisfaction_score:
|
||||
typeof log.work_satisfaction_score === "number" ? Number(log.work_satisfaction_score) : null,
|
||||
note: log.note,
|
||||
}));
|
||||
const { actor, service } = await requireFreelancerBackend();
|
||||
const logs: DailyLogItem[] = service.listJournalEntries(actor)
|
||||
.slice(0, 180)
|
||||
.flatMap((entry) =>
|
||||
entry.moodScore == null || entry.energyScore == null
|
||||
? []
|
||||
: [{
|
||||
id: entry.id,
|
||||
log_date: entry.entryDate,
|
||||
mood_score: entry.moodScore,
|
||||
energy_score: entry.energyScore,
|
||||
work_satisfaction_score: entry.workSatisfactionScore,
|
||||
note: entry.note,
|
||||
}],
|
||||
);
|
||||
|
||||
return <JournalClient logs={logs} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user