PHP Rebuild
CI / ci (push) Canceled after 0s

Initial PHP rebuild of the app
This commit is contained in:
Stefan Lazic committed 2026-09-05 08:21:33 +01:00
1 parent 8a2b211069
commit 2ef3654841
690 files changed
+33944 -12046

No files matched your search

@@ -1,41 +0,0 @@
"use server";
import { revalidatePath } from "next/cache";
import { auth } from "@/auth";
import { prisma } from "@/lib/db/prisma";
import { markAllNotificationsRead, markNotificationRead } from "@/services/notifications/notification.service";
export interface MarkReadActionResult {
success: boolean;
error?: string;
}
/**
* Shared across all three notification-centre pages (customer/staff/owner)
* — ownership is enforced by recipientUserId matching the session, exactly
* the same rule regardless of which role is asking (see
* NotificationService.markNotificationRead's own scoped WHERE clause), so
* one action file covers all of them rather than three near-identical
* copies.
*/
export async function markNotificationReadAction(notificationId: string): Promise<MarkReadActionResult> {
const session = await auth();
if (!session?.user) return { success: false, error: "You must be signed in." };
await markNotificationRead(prisma, { notificationId, userId: session.user.id });
revalidatePath("/notifications");
revalidatePath("/staff/notifications");
revalidatePath("/owner/notifications");
return { success: true };
}
export async function markAllNotificationsReadAction(): Promise<MarkReadActionResult> {
const session = await auth();
if (!session?.user) return { success: false, error: "You must be signed in." };
await markAllNotificationsRead(prisma, session.user.id);
revalidatePath("/notifications");
revalidatePath("/staff/notifications");
revalidatePath("/owner/notifications");
return { success: true };
}
@@ -1,35 +0,0 @@
"use server";
import { auth } from "@/auth";
import { NotificationType } from "@/generated/prisma/enums";
import { prisma } from "@/lib/db/prisma";
import { setNotificationPreference } from "@/services/notifications/notification.service";
import type { PreferenceCellState } from "@/features/staff/components/notification-preferences-form";
export interface PreferencesActionResult {
success: boolean;
error?: string;
}
/**
* The customer-side counterpart to features/staff/actions/profile.ts's
* saveNotificationPreferencesAction — same shape, but scoped to the
* session's own customer account and the one preference-controlled
* customer-facing type (BOOKING_REMINDER; see notifications/types.ts).
*/
export async function saveCustomerNotificationPreferencesAction(
cells: PreferenceCellState[],
): Promise<PreferencesActionResult> {
const session = await auth();
if (!session?.user) return { success: false, error: "You must be signed in." };
for (const cell of cells) {
await setNotificationPreference(prisma, {
userId: session.user.id,
type: NotificationType.BOOKING_REMINDER,
channel: cell.channel,
isEnabled: cell.isEnabled,
});
}
return { success: true };
}
@@ -1,51 +0,0 @@
"use server";
import { auth } from "@/auth";
import { prisma } from "@/lib/db/prisma";
import { getPrimaryBusiness } from "@/lib/business/get-primary-business";
import { subscribeToPush, unsubscribeFromPush } from "@/services/notifications/push-subscription.service";
export interface PushActionResult {
success: boolean;
error?: string;
}
/**
* Registered users only (staff, owner, signed-in customer) — a guest has
* no session to attribute the subscription to. A guest subscribing right
* after a guest booking is a real, documented gap for a future pass (see
* docs/phase-7-summary.md, "Known limitations"), not an oversight.
*/
export async function subscribeToPushAction(input: {
endpoint: string;
p256dhKey: string;
authKey: string;
deviceLabel?: string;
}): Promise<PushActionResult> {
const session = await auth();
if (!session?.user) return { success: false, error: "You must be signed in." };
const [business, customerProfile] = await Promise.all([
getPrimaryBusiness(),
prisma.customerProfile.findUnique({ where: { userId: session.user.id } }),
]);
await subscribeToPush(prisma, {
businessId: business.id,
userId: session.user.id,
customerId: customerProfile?.id,
endpoint: input.endpoint,
p256dhKey: input.p256dhKey,
authKey: input.authKey,
deviceLabel: input.deviceLabel,
});
return { success: true };
}
export async function unsubscribeFromPushAction(endpoint: string): Promise<PushActionResult> {
const session = await auth();
if (!session?.user) return { success: false, error: "You must be signed in." };
await unsubscribeFromPush(prisma, { endpoint, ownerUserId: session.user.id });
return { success: true };
}