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 (run when BOT_ENABLED=true):

  • 9 AM daily — morning briefing to each active user
  • 10 AM daily — approval reminders for posts pending >24h
  • 9 AM Monday — weekly summary to each active user

Key API Routes

Post Generation: /generate_post, /regenerate_post, /edit_post, /publish_post, GET /post/:id
Client Data: /client/:id/context, /client/:id/posts, /client/:id/media, /client/:id/analytics
Telegram: /telegram/pair, /telegram/unpair, GET /telegram/status
Approval: /post/approve, /posts/pending-reminders
Brand Voice: /client/:id/brand-voice
Publishing: /publish, /publish_post
Content: /scrape, /search_images
Tracking: /track/open, /track/click
Webhooks: /webhooks/resend
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
LLM_PROVIDER=ollama|gemini   # Default: ollama
GOOGLE_API_KEY=               # Gemini
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama2
OPENROUTER_API_KEY=           # Multi-model strategy

# 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

# Cloudflare Browser Rendering
CF_API_TOKEN=
CF_ACCOUNT_ID=

# 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.