WeLe Agentic AI with Docker deployment
This commit is contained in:
+16
-12
@@ -30,15 +30,15 @@ pnpm-debug.log*
|
||||
# ── Python (voice service) ──────────────────────────────────────────────────
|
||||
voice-service/.venv/
|
||||
.venv/
|
||||
venv/
|
||||
env/
|
||||
/venv/
|
||||
/env/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.egg-info/
|
||||
.eggs/
|
||||
build/
|
||||
dist/
|
||||
/build/
|
||||
/dist/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
@@ -48,9 +48,13 @@ dist/
|
||||
# The AI4Bharat and Whisper checkpoints are several GB and are re-downloaded
|
||||
# from HuggingFace on first run. They are gated, so committing them would also
|
||||
# redistribute models the licence does not allow us to redistribute.
|
||||
.cache/
|
||||
huggingface/
|
||||
models/
|
||||
#
|
||||
# Leading slashes matter: an unanchored `models/` also matches
|
||||
# `src/data/models/` — the CRM read-models — which silently kept them out of
|
||||
# the repo and made the container crash with ERR_MODULE_NOT_FOUND.
|
||||
/.cache/
|
||||
/huggingface/
|
||||
/models/
|
||||
*.onnx
|
||||
*.safetensors
|
||||
*.ckpt
|
||||
@@ -64,7 +68,7 @@ models/
|
||||
# contain customer data.
|
||||
storage/artifacts/*
|
||||
!storage/artifacts/.gitkeep
|
||||
logs/
|
||||
/logs/
|
||||
*.log
|
||||
|
||||
# Scratch audio from voice debugging
|
||||
@@ -86,7 +90,7 @@ desktop.ini
|
||||
# ── Local tooling ───────────────────────────────────────────────────────────
|
||||
# Per-machine Claude Code settings; the shared .claude/settings.json is tracked.
|
||||
.claude/settings.local.json
|
||||
coverage/
|
||||
.nyc_output/
|
||||
tmp/
|
||||
temp/
|
||||
/coverage/
|
||||
/.nyc_output/
|
||||
/tmp/
|
||||
/temp/
|
||||
|
||||
+3
-2
@@ -33,12 +33,13 @@ services:
|
||||
- REDIS_ENABLED=true
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PREFIX=agentic:
|
||||
# Quoted: a trailing colon makes YAML parse this as a map, not a string.
|
||||
- "REDIS_PREFIX=agentic:"
|
||||
|
||||
# Writes go through the CRM's own REST routes so its lead scoring,
|
||||
# socket events and audit trail still fire. Reached over the shared
|
||||
# network, so this never leaves the host.
|
||||
- CRM_API_BASE=http://whatsapp-api:3000
|
||||
- "CRM_API_BASE=http://whatsapp-api:3000"
|
||||
|
||||
# Must match the CRM's JWT_SECRET — that is how a CRM login is accepted
|
||||
# here with the same role and permissions. Sourced from .env so the
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// ============================================
|
||||
// Read-models over the live CRM collections.
|
||||
//
|
||||
// Deliberately schema-less (`strict: false`): this service only READS from
|
||||
// these collections, and the CRM owns the real schemas. Re-declaring 26 full
|
||||
// schemas here would create two definitions of the same truth that silently
|
||||
// drift apart the first time the CRM adds a field. Collection names are
|
||||
// pinned explicitly — they were verified against the live database rather
|
||||
// than inferred from Mongoose's pluralisation rules.
|
||||
// ============================================
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
const loose = (collection) =>
|
||||
new mongoose.Schema({}, { strict: false, collection, versionKey: false });
|
||||
|
||||
const model = (name, collection) =>
|
||||
mongoose.models[name] || mongoose.model(name, loose(collection));
|
||||
|
||||
export const Lead = model('Lead', 'leads');
|
||||
export const Conversation = model('Conversation', 'conversations');
|
||||
export const LeadStage = model('LeadStage', 'leadstages');
|
||||
export const AnalyticsEvent = model('AnalyticsEvent', 'analyticsevents');
|
||||
export const SummaryNote = model('SummaryNote', 'summarynotes');
|
||||
export const WorkshopStage = model('WorkshopStage', 'workshopstages');
|
||||
export const EnrollmentLog = model('EnrollmentLog', 'enrollmentlogs');
|
||||
export const CallLog = model('CallLog', 'calllogs');
|
||||
export const CallSession = model('CallSession', 'callsessions');
|
||||
export const Campaign = model('Campaign', 'campaigns');
|
||||
export const FollowUp = model('FollowUp', 'followups');
|
||||
export const DSRReport = model('DSRReport', 'dsrreports');
|
||||
export const User = model('User', 'users');
|
||||
export const Role = model('Role', 'roles');
|
||||
export const Course = model('Course', 'courses');
|
||||
export const Trainer = model('Trainer', 'trainers');
|
||||
export const Tag = model('Tag', 'tags');
|
||||
export const StageConfig = model('StageConfig', 'stageconfigs');
|
||||
export const WhatsAppLead = model('WhatsAppLead', 'whatsappleads');
|
||||
export const CommentLead = model('CommentLead', 'commentleads');
|
||||
export const InstaAdLead = model('InstaAdLead', 'instaadleads');
|
||||
export const ScheduledEvent = model('ScheduledEvent', 'scheduledevents');
|
||||
export const EmailTemplate = model('EmailTemplate', 'emailtemplates');
|
||||
|
||||
// ── Paid acquisition / attribution ──
|
||||
export const CapiEvent = model('CapiEvent', 'capievents');
|
||||
export const WhatsAppTemplLead = model('WhatsAppTemplLead', 'whatsapptemplleads');
|
||||
|
||||
export const COLLECTIONS = {
|
||||
Lead, Conversation, LeadStage, AnalyticsEvent, SummaryNote, WorkshopStage,
|
||||
EnrollmentLog, CallLog, CallSession, Campaign, FollowUp, DSRReport, User,
|
||||
Role, Course, Trainer, Tag, StageConfig, WhatsAppLead, CommentLead,
|
||||
InstaAdLead, ScheduledEvent, EmailTemplate, CapiEvent, WhatsAppTemplLead,
|
||||
};
|
||||
Reference in New Issue
Block a user