feat(backend): register 8 Smart Actions feature flags with route gating

This commit is contained in:
saravanakumardb1 2026-04-06 11:11:25 -07:00
parent c71b01681f
commit 1b4b5af995
3 changed files with 21 additions and 0 deletions

View File

@ -17,6 +17,13 @@ const registry = createFlagRegistry({
'notelett_auto_embed_enabled': false,
'notelett_duplicate_check_enabled': true,
'notelett_suggest_links_enabled': true,
// Smart Actions feature flags (§6.3)
'notelett_smart_actions_enabled': false,
'notelett_auto_link_enabled': false,
'notelett_copilot_llm_enabled': false,
'notelett_voice_capture_enabled': false,
'notelett_scheduled_actions_enabled': false,
'notelett_webhooks_enabled': false,
},
enabled: config.FEATURE_FLAGS_ENABLED,
});

View File

@ -6,6 +6,7 @@ import type { FastifyInstance } from 'fastify';
import { z } from 'zod';
import { getUserId, getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError, NotFoundError } from '@bytelyst/errors';
import { isFeatureEnabled } from '../../lib/feature-flags.js';
import { embedText, cosineSimilarity, stripHtmlForEmbedding } from '../../lib/embeddings.js';
import { llm } from '../../lib/llm.js';
import {
@ -70,6 +71,7 @@ export async function notePromptRoutes(app: FastifyInstance): Promise<void> {
// ── Run a prompt template against a note ────────────────────────
app.post('/note-prompts/run', async (req) => {
if (!isFeatureEnabled('notelett_smart_actions_enabled')) throw new BadRequestError('Smart Actions are disabled');
const userId = getUserId(req);
const productId = getRequestProductId(req);
const input = RunPromptSchema.parse(req.body);

View File

@ -12,6 +12,7 @@ import { getUserId, getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError, NotFoundError } from '@bytelyst/errors';
import { getCollection } from '../../lib/datastore.js';
import { PRODUCT_ID } from '../../lib/product-config.js';
import { isFeatureEnabled } from '../../lib/feature-flags.js';
import { llm } from '../../lib/llm.js';
import * as noteRepo from '../notes/repository.js';
import * as promptRepo from './repository.js';
@ -241,6 +242,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
// ── Schedule CRUD ─────────────────────────────────────────────
app.get('/prompt-schedules', async (req) => {
if (!isFeatureEnabled('notelett_scheduled_actions_enabled')) throw new BadRequestError('Scheduled actions are disabled');
const userId = getUserId(req);
const items = await scheduleCollection().findMany({
filter: { productId: PRODUCT_ID, userId },
@ -251,6 +253,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.post('/prompt-schedules', async (req, reply) => {
if (!isFeatureEnabled('notelett_scheduled_actions_enabled')) throw new BadRequestError('Scheduled actions are disabled');
const userId = getUserId(req);
const input = CreateScheduleSchema.parse(req.body);
const now = new Date().toISOString();
@ -274,6 +277,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.get('/prompt-schedules/:id', async (req) => {
if (!isFeatureEnabled('notelett_scheduled_actions_enabled')) throw new BadRequestError('Scheduled actions are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const doc = await scheduleCollection().findById(id, userId);
@ -282,6 +286,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.patch('/prompt-schedules/:id', async (req) => {
if (!isFeatureEnabled('notelett_scheduled_actions_enabled')) throw new BadRequestError('Scheduled actions are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const input = UpdateScheduleSchema.parse(req.body);
@ -298,6 +303,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.delete('/prompt-schedules/:id', async (req, reply) => {
if (!isFeatureEnabled('notelett_scheduled_actions_enabled')) throw new BadRequestError('Scheduled actions are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const existing = await scheduleCollection().findById(id, userId);
@ -309,6 +315,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
// ── Webhook CRUD ──────────────────────────────────────────────
app.get('/prompt-webhooks', async (req) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const items = await webhookCollection().findMany({
filter: { productId: PRODUCT_ID, userId },
@ -319,6 +326,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.post('/prompt-webhooks', async (req, reply) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const input = CreateWebhookSchema.parse(req.body);
const now = new Date().toISOString();
@ -342,6 +350,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.get('/prompt-webhooks/:id', async (req) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const doc = await webhookCollection().findById(id, userId);
@ -350,6 +359,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.patch('/prompt-webhooks/:id', async (req) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const input = UpdateWebhookSchema.parse(req.body);
@ -361,6 +371,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
});
app.delete('/prompt-webhooks/:id', async (req, reply) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const existing = await webhookCollection().findById(id, userId);
@ -372,6 +383,7 @@ export async function promptSchedulerRoutes(app: FastifyInstance): Promise<void>
// ── Trigger a webhook (F26) ───────────────────────────────────
app.post('/prompt-webhooks/:id/trigger', async (req) => {
if (!isFeatureEnabled('notelett_webhooks_enabled')) throw new BadRequestError('Webhooks are disabled');
const userId = getUserId(req);
const { id } = req.params as { id: string };
const input = TriggerWebhookSchema.parse(req.body);