Add Docker support and notification URL enhancement

This commit is contained in:
2026-01-12 20:59:03 +01:00
parent 3121ef223d
commit 68d0584917
5 changed files with 79 additions and 4 deletions

9
.dockerignore Normal file
View File

@@ -0,0 +1,9 @@
node_modules
.next
.git
.env
prisma/dev.db
prisma/dev.db-journal
README.md
Dockerfile
.dockerignore

45
Dockerfile Normal file
View File

@@ -0,0 +1,45 @@
# Build Stage
FROM node:20-alpine AS builder
WORKDIR /app
# Install dependencies
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install
# Build the application
COPY . .
RUN npx prisma generate
RUN npm run build
# Production Stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
# Install production dependencies only
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install --omit=dev
# Copy build artifacts and necessary files
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.mjs ./
COPY --from=builder /app/next.config.ts ./
# Optional: if you have next-pwa and custom worker files
# COPY --from=builder /app/public/sw.js ./public/
# Copy prisma for migrations at runtime
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma
# Script to run migrations and start the app
RUN echo '#!/bin/sh\nnpx prisma migrate deploy\nnpm start' > start.sh
RUN chmod +x start.sh
EXPOSE 3000
CMD ["./start.sh"]

View File

@@ -2,6 +2,7 @@
import prisma from "@/lib/prisma" import prisma from "@/lib/prisma"
import { revalidatePath } from "next/cache" import { revalidatePath } from "next/cache"
import { headers } from "next/headers"
import { sendNotification } from "@/lib/notifications" import { sendNotification } from "@/lib/notifications"
export async function createBooking(planId: string, date: Date, name: string, type: "SITTER" | "OWNER_HOME" = "SITTER") { export async function createBooking(planId: string, date: Date, name: string, type: "SITTER" | "OWNER_HOME" = "SITTER") {
@@ -31,10 +32,14 @@ export async function createBooking(planId: string, date: Date, name: string, ty
}) })
if (plan?.webhookUrl && plan.notifyAll) { if (plan?.webhookUrl && plan.notifyAll) {
const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/dashboard/${planId}`
const dateStr = date.toLocaleDateString() const dateStr = date.toLocaleDateString()
const message = type === "OWNER_HOME" const message = type === "OWNER_HOME"
? `🏠 OWNER HOME: Marked for ${dateStr}.` ? `🏠 OWNER HOME: Marked for ${dateStr}.\nPlan: ${planUrl}`
: `✅ NEW BOOKING: ${name} is sitting on ${dateStr}.` : `✅ NEW BOOKING: ${name} is sitting on ${dateStr}.\nPlan: ${planUrl}`
await sendNotification(plan.webhookUrl, message) await sendNotification(plan.webhookUrl, message)
} }
@@ -54,8 +59,12 @@ export async function deleteBooking(bookingId: number, planId: string) {
}) })
if (booking.plan.webhookUrl) { if (booking.plan.webhookUrl) {
const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/dashboard/${planId}`
const dateStr = booking.date.toLocaleDateString() const dateStr = booking.date.toLocaleDateString()
await sendNotification(booking.plan.webhookUrl, `🚨 CANCELLATION: ${booking.sitterName} removed their booking for ${dateStr}.`) await sendNotification(booking.plan.webhookUrl, `🚨 CANCELLATION: ${booking.sitterName} removed their booking for ${dateStr}.\nPlan: ${planUrl}`)
} }
revalidatePath(`/dashboard/${planId}`) revalidatePath(`/dashboard/${planId}`)

View File

@@ -2,6 +2,7 @@
import prisma from "@/lib/prisma" import prisma from "@/lib/prisma"
import { revalidatePath } from "next/cache" import { revalidatePath } from "next/cache"
import { headers } from "next/headers"
import { sendNotification } from "@/lib/notifications" import { sendNotification } from "@/lib/notifications"
export async function updatePlan(planId: string, data: { instructions?: string; webhookUrl?: string; notifyAll?: boolean }) { export async function updatePlan(planId: string, data: { instructions?: string; webhookUrl?: string; notifyAll?: boolean }) {
@@ -15,7 +16,10 @@ export async function updatePlan(planId: string, data: { instructions?: string;
}) })
if (data.instructions && plan.webhookUrl && plan.notifyAll) { if (data.instructions && plan.webhookUrl && plan.notifyAll) {
await sendNotification(plan.webhookUrl, `📝 UPDATED: Cat instructions have been modified.`) const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/dashboard/${planId}`
await sendNotification(plan.webhookUrl, `📝 UPDATED: Cat instructions have been modified.\nPlan: ${planUrl}`)
} }
revalidatePath(`/dashboard/${planId}`) revalidatePath(`/dashboard/${planId}`)

8
docker-compose.yml Normal file
View File

@@ -0,0 +1,8 @@
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- ./data:/app/prisma
restart: always