fix: harden update pipeline and restore a clean production build
- update-Nitrov3.sh: build CMS into .next-staging and swap atomically so a failed build never takes the live site down; auto-merge new variables from .env.example; validate env for duplicates/broken lines; restart the emulator/CMS only when rebuilt or unhealthy; fix step renumbering - next.config.ts: support NEXT_DIST_DIR for staged production builds - fix all TS errors (unused imports, missing tryDownloadCandidates helper) so tsc and the production build pass clean - add Dockerfile/.dockerignore and switch docker-compose to a CMS container - include prevailing UI/refactor changes (SurfaceCard, ticketing, tsconfig)
This commit is contained in:
1 parent
750fcb2e5c
commit
944e8ff1d8
26 files changed
+427
-876
No files matched your search
+1
-39
@@ -3,13 +3,11 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db, WebsiteTicket, WebsiteTicketMessage } from "@/lib/db";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { adminAction, authAction } from "@/lib/safe-action";
|
||||
import { adminAction } from "@/lib/safe-action";
|
||||
import { ActionError, actionOk } from "@/lib/safe-action-shared";
|
||||
import { logAudit } from "@/lib/services/audit";
|
||||
import { notify } from "@/lib/services/webhook";
|
||||
import {
|
||||
assignTicketSchema,
|
||||
createTicketSchema,
|
||||
replyTicketSchema,
|
||||
updateTicketPrioritySchema,
|
||||
updateTicketStatusSchema,
|
||||
@@ -17,42 +15,6 @@ import {
|
||||
|
||||
// ── User actions (authenticated, no admin perms needed) ──────────────
|
||||
|
||||
export const createTicket = authAction(
|
||||
{
|
||||
schema: createTicketSchema,
|
||||
rateLimitKey: "ticket-create",
|
||||
rateLimitMax: 5,
|
||||
rateLimitWindowMs: 60_000,
|
||||
},
|
||||
async (ctx) => {
|
||||
const now = new Date();
|
||||
const [result] = await db.insert(WebsiteTicket).values({
|
||||
subject: ctx.data.subject,
|
||||
category: ctx.data.category,
|
||||
creatorId: ctx.session.user.id,
|
||||
updatedAt: now,
|
||||
});
|
||||
const ticketId = Number(result.insertId);
|
||||
|
||||
// Create the first message
|
||||
await db.insert(WebsiteTicketMessage).values({
|
||||
ticketId,
|
||||
userId: ctx.session.user.id,
|
||||
message: ctx.data.message,
|
||||
isStaff: 0,
|
||||
});
|
||||
|
||||
notify({
|
||||
action: "ticket_create",
|
||||
actor: ctx.session.user.username,
|
||||
target: `#${ticketId} - ${ctx.data.subject}`,
|
||||
details: `Category: ${ctx.data.category}`,
|
||||
});
|
||||
|
||||
return actionOk({ id: ticketId });
|
||||
},
|
||||
);
|
||||
|
||||
export const adminReplyTicket = adminAction(
|
||||
{
|
||||
permission: [PERMS.TICKETS_EDIT, PERMS.MOD_TICKETS_EDIT],
|
||||
|
||||
Reference in new issue
Block a user