|
import {join} from "node:path";
|
|
import {Configuration} from "@tsed/di";
|
|
import {application} from "@tsed/platform-http";
|
|
import "@tsed/platform-log-request"; // remove this import if you don't want log request
|
|
import "@tsed/platform-express"; // /!\ keep this import
|
|
import "@tsed/ajv";
|
|
import "@tsed/swagger";
|
|
import "@tsed/scalar";
|
|
import {config} from "./config/index.js";
|
|
import * as rest from "./controllers/rest/index.js";
|
|
import * as pages from "./controllers/pages/index.js";
|
|
import {testConnection, closePool} from "./config/database.js";
|
|
import {$log} from "@tsed/logger";
|
|
|
|
@Configuration({
|
|
...config,
|
|
acceptMimes: ["application/json"],
|
|
httpPort: process.env.PORT || 8083,
|
|
httpsPort: false, // CHANGE
|
|
mount: {
|
|
"/rest": [
|
|
...Object.values(rest)
|
|
],
|
|
"/": [
|
|
...Object.values(pages)
|
|
]
|
|
},
|
|
swagger: [
|
|
{
|
|
path: "/doc",
|
|
specVersion: "3.0.1",
|
|
spec: {
|
|
info: {
|
|
title: "Candivista API",
|
|
version: process.env.APP_VERSION || "1.0.0",
|
|
description:
|
|
"REST API for Candivista. Authentication via JWT Bearer tokens.\n\n" +
|
|
"Includes endpoints for auth, users, jobs, tokens, AI-powered interviews (OpenRouter/Ollama), payment processing, and admin reporting.\n\n" +
|
|
"AI Features:\n" +
|
|
"- OpenRouter integration for cloud-based AI interviews\n" +
|
|
"- Ollama support for local AI processing\n" +
|
|
"- Test mode for admin interview testing\n" +
|
|
"- Mandatory question support before AI interviews\n\n" +
|
|
"Payment Features:\n" +
|
|
"- Stripe integration for secure payments\n" +
|
|
"- Support for credit cards, iDEAL, and bank transfers\n" +
|
|
"- Dynamic token pricing with package discounts\n" +
|
|
"- Custom token quantity purchases\n" +
|
|
"- Webhook-based payment confirmation",
|
|
contact: {
|
|
name: "Candivista Team",
|
|
url: "https://candivista.com",
|
|
email: "support@candivista.com"
|
|
},
|
|
license: { name: "Proprietary" }
|
|
},
|
|
servers: [
|
|
{ url: "http://localhost:8083", description: "Local" }
|
|
],
|
|
tags: [
|
|
{ name: "Auth", description: "Authentication and session management" },
|
|
{ name: "Users", description: "User profile and token summary" },
|
|
{ name: "Jobs", description: "Job posting and interview token operations" },
|
|
{ name: "Admin", description: "Administrative statistics and management" },
|
|
{ name: "AI", description: "AI-powered interview operations with OpenRouter and Ollama support" },
|
|
{ name: "Payments", description: "Stripe payment processing for token purchases" },
|
|
{ name: "Webhooks", description: "Stripe webhook handlers for payment events" }
|
|
],
|
|
components: {
|
|
securitySchemes: {
|
|
bearerAuth: { type: "http", scheme: "bearer", bearerFormat: "JWT" }
|
|
}
|
|
},
|
|
security: [{ bearerAuth: [] }]
|
|
}
|
|
}
|
|
],
|
|
scalar: [
|
|
{
|
|
path: "/scalar/doc",
|
|
specVersion: "3.0.1"
|
|
}
|
|
],
|
|
middlewares: [
|
|
"cors",
|
|
"cookie-parser",
|
|
"compression",
|
|
"method-override",
|
|
"json-parser",
|
|
{ use: "urlencoded-parser", options: { extended: true }}
|
|
],
|
|
views: {
|
|
root: join(process.cwd(), "views"),
|
|
extensions: {
|
|
ejs: "ejs"
|
|
}
|
|
}
|
|
})
|
|
export class Server {
|
|
protected app = application();
|
|
|
|
async $onInit() {
|
|
// Test database connection on startup
|
|
const isConnected = await testConnection();
|
|
if (!isConnected) {
|
|
$log.error("Failed to connect to database. Server will continue but database operations may fail.");
|
|
}
|
|
}
|
|
|
|
async $onDestroy() {
|
|
// Close database pool on shutdown
|
|
await closePool();
|
|
}
|
|
}
|