YAS/apps/api/src/main.ts
YetAnotherSuite Dev 0afbae8944 feat: Phase 4 AI intelligence — writing assistant, semantic search, knowledge graph
Phase 4.1: AI Writing Assistant
- GPT-4o integration with OpenAI API (fallback to local parsing)
- Six AI actions: summarize, expand, rewrite, extract actions,
  suggest links, smart schedule
- TipTap inline AI assistant panel with streaming-ready architecture
- Apply/dismiss UI for AI suggestions
- Rewrite style selector (concise, formal, simpler, detailed)

Phase 4.2: Natural Language Input
- /api/v1/natural-language endpoint for parsing unstructured text
- AI-powered extraction of type, title, date, priority, participants
- Local regex fallback when no API key configured
- Priority parsing (!1-5) and date detection (tomorrow, next week)

Phase 4.3: Knowledge Graph
- D3.js-ready graph visualization container
- Zoom in/out/fit controls
- Placeholder state with guidance for content creation
- Data model for nodes, links, and groups

Phase 4.4: Semantic Search Infrastructure
- Unified search bar with debounced input (300ms)
- Type-based result icons (note, task, event)
- Search result display with title and content preview
- pgvector and embedding pipeline data model in schema
2026-07-20 22:22:54 +02:00

74 lines
2.5 KiB
TypeScript

import Fastify from 'fastify';
import cors from '@fastify/cors';
import helmet from '@fastify/helmet';
import rateLimit from '@fastify/rate-limit';
import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUi from '@fastify/swagger-ui';
import fastifyWebsocket from '@fastify/websocket';
import fastifyCookie from '@fastify/cookie';
import fastifyJwt from '@fastify/jwt';
import { PrismaClient } from '@yetanother/db';
import { API_PREFIX } from '@yetanother/utils';
import { authPlugin } from './plugins/auth.js';
import { authRoutes } from './routes/auth.js';
import { nodeRoutes } from './routes/nodes.js';
import { workspaceRoutes } from './routes/workspaces.js';
import { searchRoutes } from './routes/search.js';
import { aiRoutes } from './routes/ai.js';
const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : 4000;
const envHost = process.env.HOST ?? '0.0.0.0';
const jwtSecret = process.env.JWT_SECRET ?? 'dev-secret-change-in-production';
export async function buildApp() {
const prisma = new PrismaClient();
const app = Fastify({
logger: {
transport: process.env.NODE_ENV !== 'production'
? { target: 'pino-pretty', options: { colorize: true } }
: undefined,
},
});
await app.register(cors, { origin: true, credentials: true });
await app.register(helmet, { contentSecurityPolicy: false });
await app.register(rateLimit, { max: 100, timeWindow: '1 minute' });
await app.register(fastifyCookie);
await app.register(fastifyJwt, { secret: jwtSecret });
await app.register(fastifyWebsocket);
await app.register(fastifySwagger, {
openapi: {
info: { title: 'YetAnotherSuite API', version: '1.0.0' },
},
});
await app.register(fastifySwaggerUi, { routePrefix: '/docs' });
app.decorate('prisma', prisma);
await app.register(authPlugin);
await app.register(authRoutes, { prefix: `${API_PREFIX}/auth` });
await app.register(nodeRoutes, { prefix: API_PREFIX });
await app.register(workspaceRoutes, { prefix: API_PREFIX });
await app.register(searchRoutes, { prefix: API_PREFIX });
await app.register(aiRoutes, { prefix: API_PREFIX });
app.get('/health', async () => ({ status: 'ok', timestamp: new Date().toISOString() }));
return app;
}
async function main() {
const app = await buildApp();
try {
await app.listen({ port: envPort, host: envHost });
app.log.info(`Server running at http://${envHost}:${envPort}`);
} catch (err) {
app.log.error(err);
throw err;
}
}
main();