feat: Enhance provider components with detailed documentation and comments
- Added comprehensive comments and JSDoc-style documentation to NotificationProvider, ThemeProvider, UserProvider, and WebsiteThemeProvider for better clarity and maintainability. - Improved type definitions in index.ts for better code understanding and usage. - Introduced Docker support with Dockerfiles for various services including AI server, signaling server, and browser-use service. - Created a docker-compose.yml file to orchestrate multiple services including PostgreSQL, AI, scraper, and frontend. - Added a startup guide (startup.txt) for setting up the CRM environment on Ubuntu with Docker. - Included a .dockerignore file to exclude unnecessary files from Docker builds.
This commit is contained in:
@@ -60,6 +60,7 @@ let pullProgress = { status: "idle", progress: 0, message: "" }
|
||||
// ── Job loading ─────────────────────────────────────────────────
|
||||
// Loads job categories from a JSONL file (one JSON object per line).
|
||||
// Used as context for the AI sales coach chat responses.
|
||||
/** Load job categories from the JSONL file at JOBS_PATH. Returns an array of parsed job objects. */
|
||||
function loadJobs() {
|
||||
try {
|
||||
const content = fs.readFileSync(JOBS_PATH, "utf-8")
|
||||
@@ -86,6 +87,7 @@ function loadJobs() {
|
||||
// ── ai.md management ────────────────────────────────────────────
|
||||
// ai.md is a Markdown file containing system instructions for the AI.
|
||||
// It can be read, written, or appended to via the API.
|
||||
/** Read the full contents of ai.md. Returns empty string if the file doesn't exist yet. */
|
||||
function readInstructions() {
|
||||
try {
|
||||
return fs.readFileSync(AI_MD_PATH, "utf-8")
|
||||
@@ -94,11 +96,13 @@ function readInstructions() {
|
||||
}
|
||||
}
|
||||
|
||||
/** Overwrite ai.md with new content. Returns the content that was written. */
|
||||
function writeInstructions(content) {
|
||||
fs.writeFileSync(AI_MD_PATH, content, "utf-8")
|
||||
return content
|
||||
}
|
||||
|
||||
/** Append a timestamped entry to the ## Improvement Log section of ai.md. Creates the section if it doesn't exist. */
|
||||
function appendToImprovementLog(entry) {
|
||||
// Adds a timestamped entry to the ## Improvement Log section of ai.md
|
||||
const current = readInstructions()
|
||||
@@ -153,6 +157,7 @@ async function scrapeFacebook() {
|
||||
}
|
||||
}
|
||||
|
||||
/** Format scraped Facebook leads into a human-readable Markdown string for the AI chat response. */
|
||||
function formatLeads(leads) {
|
||||
if (!leads || leads.length === 0) return "No leads found from the latest scrape."
|
||||
let output = `**${leads.length} leads found:**\n\n`
|
||||
@@ -239,6 +244,7 @@ Provide concise, actionable sales advice. When asked about a specific job catego
|
||||
// ── PG pool (lazy init) ────────────────────────────────────────
|
||||
// PostgreSQL connection pool for storing conversation history.
|
||||
// Lazy-initialized so the server starts even without a DB.
|
||||
/** Lazy-initialize the PostgreSQL connection pool. Non-blocking — server works without a database. */
|
||||
let pgPool = null
|
||||
async function initPg() {
|
||||
if (!DATABASE_URL) return
|
||||
@@ -255,11 +261,13 @@ async function initPg() {
|
||||
// ── Request router ─────────────────────────────────────────────
|
||||
const loadedJobs = loadJobs()
|
||||
|
||||
/** Write a JSON response with the given HTTP status code. */
|
||||
function sendJSON(res, status, data) {
|
||||
res.writeHead(status, { "Content-Type": "application/json" })
|
||||
res.end(JSON.stringify(data))
|
||||
}
|
||||
|
||||
/** Parse the JSON body of an incoming HTTP request. */
|
||||
function parseBody(req) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let body = ""
|
||||
@@ -275,6 +283,7 @@ function parseBody(req) {
|
||||
})
|
||||
}
|
||||
|
||||
/** Parse a request URL into its pathname and search params. Falls back to localhost if no Host header is present. */
|
||||
function parseURL(req) {
|
||||
const url = new URL(req.url, `http://${req.headers.host || "localhost"}`)
|
||||
return { pathname: url.pathname, searchParams: url.searchParams }
|
||||
|
||||
Reference in New Issue
Block a user