fix(backend): review fixes — persist requiresApproval, shutdown hook, productId check, GET by ID

- repository.ts: persist requiresApproval field in createPromptTemplate (was silently dropped)
- server.ts: register onClose hook to call stopSchedulerLoop() on graceful shutdown
- scheduler.ts: add productId check in webhook trigger note lookup
- scheduler.ts: add GET /prompt-schedules/:id and GET /prompt-webhooks/:id endpoints
This commit is contained in:
saravanakumardb1 2026-04-06 10:45:03 -07:00
parent 3260b7ea0a
commit f2c3258b53
3 changed files with 20 additions and 2 deletions

View File

@ -40,6 +40,7 @@ export async function createPromptTemplate(
outputType: input.outputType ?? 'new_note',
category: input.category ?? 'transform',
isBuiltin: false,
requiresApproval: input.requiresApproval ?? false,
model: input.model,
temperature: input.temperature,
maxTokens: input.maxTokens,

View File

@ -272,6 +272,14 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
return doc;
});
app.get('/prompt-schedules/:id', async (req) => {
const userId = getUserId(req);
const { id } = req.params as { id: string };
const doc = await scheduleCollection().findById(id, userId);
if (!doc || doc.userId !== userId) throw new NotFoundError('Schedule not found');
return doc;
});
app.patch('/prompt-schedules/:id', async (req) => {
const userId = getUserId(req);
const { id } = req.params as { id: string };
@ -332,6 +340,14 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
return doc;
});
app.get('/prompt-webhooks/:id', async (req) => {
const userId = getUserId(req);
const { id } = req.params as { id: string };
const doc = await webhookCollection().findById(id, userId);
if (!doc || doc.userId !== userId) throw new NotFoundError('Webhook not found');
return doc;
});
app.patch('/prompt-webhooks/:id', async (req) => {
const userId = getUserId(req);
const { id } = req.params as { id: string };
@ -369,7 +385,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
if (!template) throw new NotFoundError('Associated template not found');
const note = await noteRepo.getNote(input.noteId, input.workspaceId);
if (!note || note.userId !== userId) throw new NotFoundError('Note not found');
if (!note || note.userId !== userId || note.productId !== PRODUCT_ID) throw new NotFoundError('Note not found');
const noteBody = stripHtmlForEmbedding(note.body ?? '');
const result = await executePrompt(template, {

View File

@ -10,7 +10,7 @@ import { noteTaskRoutes } from './modules/note-tasks/routes.js';
import { savedViewRoutes } from './modules/saved-views/routes.js';
import { workspaceRoutes } from './modules/workspaces/routes.js';
import { notePromptRoutes } from './modules/note-prompts/routes.js';
import { promptSchedulerRoutes, startSchedulerLoop } from './modules/note-prompts/scheduler.js';
import { promptSchedulerRoutes, startSchedulerLoop, stopSchedulerLoop } from './modules/note-prompts/scheduler.js';
import { initCosmosIfNeeded } from './lib/cosmos-init.js';
import { initEncryption } from './lib/field-encrypt.js';
import { initDatastore } from './lib/datastore.js';
@ -68,6 +68,7 @@ await registerApiPlugin(promptSchedulerRoutes);
// ── Start scheduler loop (F25) ────────────────────────────────────
startSchedulerLoop();
app.addHook('onClose', async () => { stopSchedulerLoop(); });
// ── Public read-only share (no auth) ───────────────────────────────
app.get('/api/public/note-shares/:token', async (req, reply) => {