initial deployment v1.0

This commit is contained in:
RaineAllDay
2026-03-18 03:06:27 -06:00
commit eaaadd39e4
69 changed files with 10755 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
import { json, error } from '@sveltejs/kit';
import { softDeletePersonality, getPersonalityById } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function POST({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const { id } = await request.json().catch(() => ({}));
if (!id) throw error(400, 'Missing personality id');
const record = getPersonalityById(id);
if (!record) throw error(404, 'Personality not found');
if (record.deleted_at) throw error(400, 'Already deleted');
softDeletePersonality(id);
return json({ success: true });
}

View File

@@ -0,0 +1,14 @@
import { json, error } from '@sveltejs/kit';
import { resolveReport } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function POST({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const { id } = await request.json().catch(() => ({}));
if (!id) throw error(400, 'Missing report id');
resolveReport(id, 1);
return json({ success: true });
}

View File

@@ -0,0 +1,32 @@
import { json, error } from '@sveltejs/kit';
import { getPersonalityById, updatePersonalityMeta } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function PATCH({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const body = await request.json().catch(() => null);
if (!body?.id) throw error(400, 'Missing id');
const record = getPersonalityById(body.id);
if (!record) throw error(404, 'Personality not found');
if (record.deleted_at) throw error(400, 'Cannot edit a deleted personality');
const name = typeof body.name === 'string' ? body.name.trim().slice(0, 120) : record.name;
const prs_name = typeof body.prs_name === 'string' ? body.prs_name.trim().slice(0, 12) : record.prs_name;
const manufacturer = typeof body.manufacturer === 'string' ? body.manufacturer.trim().slice(0, 128) : record.manufacturer;
const notes = typeof body.notes === 'string' ? body.notes.trim().slice(0, 1000) : record.notes;
const creator_handle = typeof body.creator_handle === 'string' ? body.creator_handle.trim().slice(0, 64) : record.creator_handle;
const rawTags = Array.isArray(body.tags) ? body.tags : JSON.parse(record.tags ?? '[]');
const tags = JSON.stringify(
rawTags.slice(0, 10).map(t => String(t).trim().toLowerCase().slice(0, 32)).filter(Boolean)
);
if (!name) throw error(400, 'Library name is required');
updatePersonalityMeta(body.id, { name, prs_name, manufacturer, notes, tags, creator_handle });
return json({ success: true });
}

View File

@@ -0,0 +1,20 @@
import { json, error } from '@sveltejs/kit';
import { markMessageRead, markAllMessagesRead } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function POST({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const { id, all } = await request.json().catch(() => ({}));
if (all) {
markAllMessagesRead();
} else if (id) {
markMessageRead(id);
} else {
throw error(400, 'Missing id or all flag');
}
return json({ success: true });
}

View File

@@ -0,0 +1,13 @@
import { json, error } from '@sveltejs/kit';
import { listContactMessages } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function GET({ cookies, url }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const unreadOnly = url.searchParams.get('unread') === '1';
const messages = listContactMessages({ unreadOnly });
return json({ messages });
}

View File

@@ -0,0 +1,61 @@
import { json, error } from '@sveltejs/kit';
import { getPersonalityById, replacePersonalityBinary } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
import { FILE_SIZE } from '$lib/prs.js';
const NAME_OFFSET = 0x0e;
const NAME_LEN = 12;
const CH_COUNT_OFFSET = 0x0d;
function readPrsName(bytes) {
let name = '';
for (let i = 0; i < NAME_LEN; i++) {
if (bytes[NAME_OFFSET + i] === 0) break;
name += String.fromCharCode(bytes[NAME_OFFSET + i]);
}
return name.trim();
}
export async function POST({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const body = await request.json().catch(() => null);
if (!body?.id || !body?.data) throw error(400, 'Missing id or data');
const record = getPersonalityById(body.id);
if (!record) throw error(404, 'Personality not found');
if (record.deleted_at) throw error(400, 'Cannot replace binary of a deleted personality');
const bytes = new Uint8Array(body.data);
if (bytes.length !== FILE_SIZE) {
throw error(400, `Invalid file size: expected ${FILE_SIZE} bytes, got ${bytes.length}`);
}
const newPrsName = readPrsName(bytes);
const newChannelCount = bytes[CH_COUNT_OFFSET];
// Preview mode — return diff without saving
if (body.preview) {
return json({
preview: true,
current: {
prs_name: record.prs_name ?? '',
channel_count: record.channel_count
},
incoming: {
prs_name: newPrsName,
channel_count: newChannelCount
}
});
}
// Commit — replace the binary
replacePersonalityBinary(body.id, {
data: Buffer.from(bytes),
prs_name: newPrsName,
channel_count: newChannelCount
});
return json({ success: true, prs_name: newPrsName, channel_count: newChannelCount });
}

View File

@@ -0,0 +1,15 @@
import { json } from '@sveltejs/kit';
import { getOpenReportCount, getUnreadMessageCount } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
export async function GET({ cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) {
return json({ count: null });
}
const reports = getOpenReportCount();
const messages = getUnreadMessageCount();
return json({ count: reports + messages, reports, messages });
}