Ai-Mee Help Centre
Home
Features
How-To Guides
FAQ
Need Help?
Home
Features
How-To Guides
FAQ
Need Help?

Quick Reference: AI Marketing Platform

Architecture Overview

The platform is a multi-service SaaS with two main services:

  • api/ — Node.js/Fastify API. Handles post generation, publishing, OAuth, and runs the in-process bot module.
  • front-end/ — Vue 3 SPA. Client-facing dashboard.

Supabase is the single database/auth backend. The Aimee bot runs in-process inside the API (not as a separate container) using LangChain + Telegraf.

Bot Architecture (api/src/bot/)

Telegram → TelegramAdapter.onMessage()
  → resolve user_id via messaging_users table
  → load chat_history from Supabase
  → invoke LangChain tool-calling agent
  → agent calls service functions directly
  → TelegramAdapter.sendMessage()
  → save turn to chat_history

Files:

FilePurpose
bot/index.tsAdapter registry + boot (startBot/stopBot)
bot/agent.tsLangChain tool-calling agent (Aimee)
bot/tools.tsService functions wrapped as LangChain tools
bot/memory.tsConversation state (chat_history table)
bot/cron.tsnode-cron: briefing, reminders, summary
bot/logger.tsNamespaced pino logger
bot/channels/telegram.tsTelegraf adapter
bot/prompts/system.tsMain agent system prompt

Cron jobs (pg-boss; schedules are upserted on boot — see api/src/bot/cron.ts):

  • 8:30 AM daily — morning briefing to each active user
  • 9 AM daily — integration setup reminders
  • 3 PM Friday — weekly summary (stats + AI narrative + tips) to each active user
  • 3 AM daily — website re-scrape
  • 3 AM daily — knowledge-base consolidation
  • 2 AM daily — email-segment sync
  • 8 AM daily — auto-generate posts
  • Every 5 min — scheduled publish dispatcher

Bot commands (registered via BOT_COMMANDS in api/src/bot/index.ts):

  • /start — pair your account or get a welcome message (Telegram)
  • /help — list available commands
  • /stop_reminders — disable integration reminder messages
  • /add-note [client name]: [note] — append a note to a client's notes (drives future content)
  • Any other text → routed to the LangChain Aimee agent

Key API Routes

Post Generation: /posts, /plan_posts, /regenerate_post, /edit_post, /publish_post, GET /post/:id
Client Data: /client/:id/context, /client/:id/posts, /client/:id/media, /client/:id/analytics
Forum Research: POST /client/:id/forum/research — search forum threads for content ideas
Telegram: /telegram/pair, /telegram/unpair, GET /telegram/status
WhatsApp: /whatsapp/pair, /whatsapp/webhook (public)
Approval: /post/approve, /posts/pending-reminders
Brand Voice: /client/:id/brand-voice
Publishing: /publish, /publish/test-email, /publish_post, /generate_image
Content: /scrape, /search_images
Tracking: /track/open, /track/click (public, no auth)
Webhooks: /webhooks/resend, /webhooks/stripe (public, HMAC-signature-verified)
Health: GET /health, GET /ready (public, no auth)
Admin: GET /admin/customers, POST /admin/customers/:id/trigger-briefing

Database Tables (Key)

TablePurposeKey Fields
customer_customerClients/companiesid, name, description, industries
customer_campaignCampaigns per customerstart_date, end_date, target_post_count, cadence_goal
customer_postsPost recordsstatus (new→pending_review→approved→scheduled→sent)
customer_platform_postPer-platform contentplatform, content, images, character_count
messaging_usersChannel pairings (Telegram etc.)user_id, channel, external_id, is_active
chat_historyBot conversation turnsuser_id, channel, external_id, role, content
client_brand_voiceBrand rulesrule_type (tone/terminology/audience/style), rule_text
client_content_assetUploaded/scraped assetsasset_type (image/document/video), url, content
post_analyticsPerformance metricsmetric_type, metric_value
post_feedbackClient feedback on draftsfeedback_type (approve/reject/request_edit)
customer_integrationOAuth credentials per clientintegration, metadata (JSONB, AES-256 encrypted)
marketing_calendarIndustry events/holidaysevent_name, event_date, industry

Environment Variables

All accessed via api/src/config/env.ts. Key vars:

# Database & Auth
SUPABASE_URL=
SUPABASE_KEY=
SUPABASE_SERVICE_ROLE_KEY=   # Bypasses RLS — server-side bot ops only

# LLM — OpenRouter is the primary provider (set OPENROUTER_LLM_ENABLED=true)
OPENROUTER_LLM_ENABLED=true                      # Switch to OpenRouter; falls back to Ollama/Gemini when false
OPENROUTER_API_KEY=                              # Required when OPENROUTER_LLM_ENABLED=true
OPENROUTER_MODEL_REASONING=anthropic/claude-opus-4-6      # Tier: reasoning
OPENROUTER_MODEL_CREATIVE=google/gemini-3.5-flash         # Tier: creative
OPENROUTER_MODEL_FAST=google/gemini-3.1-flash-lite        # Tier: fast

# Image generation (OpenRouter image models)
IMAGE_GENERATION_ENABLED=true                    # Set false to disable
IMAGE_GENERATION_MODEL=google/gemini-3.1-flash-image-preview
IMAGE_GENERATION_BUCKET=generated-images

# Legacy LLM providers (fallback when OPENROUTER_LLM_ENABLED is unset)
LLM_PROVIDER=ollama
GOOGLE_API_KEY=                                  # Gemini
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama2

# Bot
BOT_ENABLED=true              # Enables Telegraf + cron jobs
TELEGRAM_BOT_TOKEN=           # Telegraf bot token
CRON_TIMEZONE=UTC

# Publishing
GHOST_API_URL=
GHOST_ADMIN_API_KEY=
RESEND_API_KEY=
RESEND_FROM_EMAIL=
RESEND_FROM_NAME=
RESEND_WEBHOOK_SECRET=

# OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

# Content
UNSPLASH_ACCESS_KEY=
SERPAPI_API_KEY=

# Security
INTEGRATION_ENCRYPTION_KEY=  # 32-byte hex, AES-256-GCM
API_KEY=                      # Shared secret for internal workers/scheduler

# URLs
API_BASE_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3547

# Crawler
CHROMIUM_PATH=/usr/bin/chromium-browser

# Error Tracking
SENTRY_DSN=

Commands

api/

pnpm dev           # Start dev server with tsx watch (port 8000)
pnpm build         # tsc compile to dist/
node --test        # Run legacy tests (tests/*.test.ts)
pnpm test:routes   # Run Vitest route tests

# Single legacy test:
node --test tests/createEmailTemplate.test.ts

# Single Vitest route test:
pnpm vitest run tests/routes/phase2.test.ts

front-end/

pnpm dev           # Vite dev server on port 3547
pnpm build         # Vite production build
pnpm test          # Runs test:tsc + test:unit in parallel
pnpm test:unit     # Vitest unit tests (happy-dom)
pnpm test:tsc      # vue-tsc type check
pnpm test:e2e      # Playwright E2E tests

# Single unit test:
pnpm vitest run tests/unit/<file>.spec.ts

# Single E2E test:
pnpm playwright test tests/e2e/<file>.spec.ts

File Structure (Key Paths)

api/src/
├── index.ts              # Server entry + route registration
├── config/env.ts         # All env vars
├── bot/                  # In-process bot module (Aimee)
│   ├── index.ts
│   ├── agent.ts
│   ├── tools.ts
│   ├── memory.ts
│   ├── cron.ts
│   ├── channels/telegram.ts
│   └── prompts/
├── routes/               # Fastify route plugins
│   ├── posts.ts
│   ├── clients.ts
│   ├── content.ts
│   ├── telegram.ts
│   ├── integrations.ts
│   ├── tracking.ts
│   ├── webhooks.ts
│   └── admin.ts
├── agents/               # LLM content generation
├── integrations/         # Publishing adapters
├── modules/              # Business logic
├── services/             # Service layer
└── utils/                # Supabase client, LLM factory, etc.

front-end/src/
├── pages/                # File-based routes (unplugin-vue-router)
│   ├── auth/             # Login, signup, profile
│   └── app/              # Dashboard pages
├── components/
│   ├── ui/               # shadcn-vue components (auto-imported)
│   └── pages/            # Page-specific components
├── composables/          # Auto-imported composables
├── stores/               # Pinia stores (auto-imported)
├── utils/                # Auto-imported utilities
└── css/app.css           # Tailwind v4 @theme tokens (source of truth for design)

Publishing Adapters

FilePlatformCredentials location
integrations/twitter.tsTwitter/Xcustomer_integration.metadata (api_key, access_token…)
integrations/linkedin.tsLinkedInaccess_token + metadata.person_urn
integrations/facebook.tsFacebookaccess_token + metadata.page_id
integrations/mailchimp.tsMailchimpmetadata (api_key, list_id, server_prefix…)
integrations/ghost-adapter.tsGhost CMSglobal env vars (GHOST_API_URL, GHOST_ADMIN_API_KEY)

All adapters are invoked via POST /publish in src/routes/content.ts.