Development Plan v1.0

Nanic Ayurveda
AI Business Brain

A production-grade Telegram group bot powered by Claude Code CLI — a complete autonomous brain for Nanic Ayurveda's operations, server management, business intelligence, and customer support.

Bot Username @nanicayurveda_bot
Server 88.222.214.65 (Nanic)
Deploy Path /home/nanic/Bot
AI Engine Claude Sonnet 4.6 (Code CLI)
Interface Telegram Group (Group-Only)
Status Planning → Build

01 Technology Stack

Every component chosen for reliability, speed, and simplicity of operation on the Nanic server.

LayerTechnologyWhyTag
Telegram Interface python-telegram-bot 21.x Latest async PTB, built-in JobQueue (APScheduler), excellent group support Core
AI Backend Claude Code CLI (subprocess) User specified OAuth token approach; full tool use, file access, server control Core
Claude Model claude-sonnet-4-6 Best balance of intelligence and speed for group chat responses Core
Auth CLAUDE_CODE_OAUTH_TOKEN Long-lived token from ~/.claude/.credentials.json (re-authed April 2026) Auth
Primary DB PostgreSQL 16 Sessions, memory metadata, business data, message log — all persistent Data
Session Cache SQLite (local file) Ultra-fast session_id lookups without network overhead; file in /app/data/ Data
Memory Files Markdown files + MEMORY.md index Same pattern as ragul-bot; Claude reads/writes its own memory. Survives container restart via volume Memory
Scheduler APScheduler (via PTB JobQueue) Built into python-telegram-bot — zero extra dependency for daily briefing Jobs
Media Handling aiohttp + filesystem Download to /tmp/nanic_bot/{msg_id}/, tell Claude the path — uses its file tools Media
Deployment Docker Compose Isolated, restartable, mountable — matches existing Nanic server pattern Deploy

02 System Architecture

Five-layer design from Telegram message to server action.

┌─────────────────────────────────────────────────────────────────┐ │ TELEGRAM LAYER │ │ GroupMessageHandler │ CallbackHandler │ CommandHandler │ │ [group/supergroup only — DMs silently dropped] │ └──────────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────────▼──────────────────────────────────┐ │ ORCHESTRATION LAYER │ │ ChatQueue (asyncio.Queue per chat_id — serial, no overlap) │ │ MediaProcessor │ TypewriterEffect │ IntentParser │ RateGuard │ └──────────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────────▼──────────────────────────────────┐ │ CLAUDE INTEGRATION LAYER │ │ ClaudeBridge → subprocess → --print --output-format stream-json │ │ SessionManager │ ContextBuilder │ MemoryInjector │ TokenGuard │ └──────────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────────▼──────────────────────────────────┐ │ PERSISTENCE LAYER │ │ PostgreSQL: sessions │ memory_meta │ business_data │ msg_log │ │ SQLite: fast session_id cache │ │ Files: /app/data/memory/*.md (MEMORY.md index) │ └──────────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────────▼──────────────────────────────────┐ │ SERVER CONTROL LAYER │ │ Workspace: /home/nanic (full mount) │ │ Docker: /var/run/docker.sock │ │ Claude: --dangerously-skip-permissions, cwd=/home/nanic │ └─────────────────────────────────────────────────────────────────┘

03 Project File Structure

Modular, production-grade layout. Each module has one clear responsibility.

/home/nanic/Bot/ ├── handlers/ │ ├── group.py # group message handler (text, photos, docs) │ ├── callback.py # refresh button + inline actions │ └── commands.py # /status /reset /help /memory ├── claude/ │ ├── bridge.py # subprocess wrapper (collect full output) │ ├── session.py # per-chat session: load/save/expire (8h) │ └── context.py # system prompt builder + CLAUDE.md injection ├── memory/ │ └── manager.py # MEMORY.md index + .md files + intent parser ├── db/ │ └── database.py # asyncpg pool: sessions, business_data, msg_log ├── jobs/ │ └── briefing.py # daily 7:30 AM IST briefing via APScheduler ├── utils/ │ ├── formatters.py # HTML formatting, split long messages │ ├── media.py # download photo/doc → /tmp/nanic_bot/{id}/ │ └── queue.py # asyncio.Queue per chat_id ├── docs/ # this plan site │ └── plan.html ├── bot.py # main entry point ├── CLAUDE.md # server context injected into every Claude call ├── Dockerfile ├── docker-compose.yml ├── requirements.txt ├── entrypoint.sh └── .env # Docker volumes (persistent) bot_data → /app/data/ (memory files, SQLite, temp) pgdata → PostgreSQL data /home/nanic → mounted into container (full server access) ~/.claude → Claude auth + session history

04 Message Flow

Every message follows this exact path. Non-streaming by design — wait for full response.

1
Receive & Filter
Message arrives from Telegram. Check chat.type — if private or channel, silently drop. Rate-check: max 5 msgs/min per user. Add to ChatQueue[chat_id].
2
Show Thinking Indicator
Send typing action + a "🤔 Thinking..." reply message. This appears instantly, before Claude is called. Gives immediate feedback to the group.
3
Prepare Context
Load session_id from SQLite. Download media to /tmp/nanic_bot/{msg_id}/. Build message string: "[Username]: {text}\n[Image: /tmp/...jpg]". Inject recent memory from MEMORY.md. Build system prompt.
4
Call Claude (Blocking)
Run claude --print --output-format stream-json --model claude-sonnet-4-6 --dangerously-skip-permissions --resume <session_id> -- <message> as subprocess. Collect ALL output. Parse stream-json events. Wait up to 5 minutes. Extract response text + new session_id.
5
Parse & Save
Parse [REMEMBER: ...] tags → save to MEMORY.md. Save new session_id to SQLite. Log message to PostgreSQL. Strip internal tags from response text.
6
Send Response + Refresh Button
Delete the "🤔 Thinking..." message. Send the actual response as a new message. Attach a "🔄 Refresh" inline button. After 30 seconds, the button auto-removes (asyncio.sleep task).
7
On Refresh Click
Edit the message to show "🔄 Refreshing...". Re-run Claude with the same original query (stored in callback data). Replace message content with new response. New 30s refresh window starts.

05 Memory & Session System

Context survives restarts. Claude builds its own memory over time.

Session Continuity
One shared session_id per group chat. Stored in SQLite for fast access. Claude resumes via --resume flag — the full conversation context is preserved in Claude's internal state.

Sessions expire after 8 hours of inactivity. On new session: injects last 5 memories as context.
File-Based Memory
Claude writes [REMEMBER: fact] tags in responses. The bot parses these and saves to /app/data/memory/ as individual .md files with frontmatter. MEMORY.md is the index.

On each new session, the top 5 relevant memories are injected into the system prompt.
Business Data (PostgreSQL)
Structured tables for: revenue logs, task lists, product catalog, customer notes. Claude can read/write via SQL commands.

Used for the daily briefing (yesterday's revenue, pending tasks).
Memory Tags
Claude uses inline tags to self-manage memory:

[REMEMBER: fact to save]
[GOAL: task | DEADLINE: date]
[DONE: completed task]
[TOPIC: current topic]

Tags are stripped from the final response before sending.

06 Daily Morning Briefing

Auto-sent to the group at 7:30 AM IST every day. Claude generates fresh content each morning.

🌿 Good morning, Nanic Ayurveda team! Here's your April 18 briefing: 📊 Yesterday's Summary Revenue: ₹12,840 from 23 orders Top seller: Ashwagandha Capsules (8 units) New customers: 4 | Returns: 0 🌱 Ayurveda Tip of the Day Focus on Chyawanprash for summer promotions — it's high in Vitamin C via Amla and perfectly aligns with immunity trends. Bundle with Giloy for a bestseller combo. 📋 Today's Plan → Follow up with 3 pending wholesale inquiries → Restock Triphala Churna (stock at 12 units, threshold: 20) → Update Instagram with new product photos 🐳 Server Health All 5 Nanic containers: ✅ healthy Disk: 62GB free / 97GB nanic_frontend: Up 6 days

Technical Implementation
Trigger: APScheduler via python-telegram-bot's JobQueue. Runs at 02:00 UTC (= 7:30 AM IST) every day.

What it does: Calls Claude with: "Generate today's morning briefing. Read the revenue log from PostgreSQL, check Docker container health, pull pending tasks from memory, and give one actionable Ayurveda business tip for today."

Claude's actions: Runs server commands (docker ps, psql query), reads memory files, generates the brief. Sends to the registered GROUP_CHAT_ID.

Persistence: Works after restart — job is re-registered on bot startup.

07 System Prompt & CLAUDE.md Design

The identity, knowledge base, and guardrails that shape every response.

You are the Nanic Ayurveda Bot — the complete business brain and operational backbone of Nanic Ayurveda. You work inside a Telegram group with the core Nanic team. Your job is to assist with EVERYTHING — no request is out of scope. You act like a trusted, highly capable team member who gets things done without being asked twice. ═══ IDENTITY ═══ Business: Nanic Ayurveda — an Ayurveda product brand Role: Autonomous business brain, server manager, advisor Server: 88.222.214.65, workspace at /home/nanic Current user: {username} (in group with others) Time: {current_time} IST ═══ WHAT YOU KNOW ═══ • Ayurveda knowledge: herbs, formulations, dosages, contraindications, seasonal recommendations • Business operations: pricing, inventory, promotions, customer handling • Server infrastructure: see CLAUDE.md for full container list and architecture • Can run shell commands, manage Docker, edit files, create static sites ═══ HOW YOU WORK ═══ • Do things first, explain after — don't ask for permission on reversible actions • For irreversible actions (delete database, stop production service): confirm once, then act • When someone asks a question, answer it directly AND proactively add what they should know • Remember things with [REMEMBER: fact] tags — these get saved to memory • Respond in the same language the user writes in (English / Tamil) ═══ PERSONALITY ═══ • Like a sharp, knowledgeable younger sibling who runs the whole business backend • Direct, helpful, zero corporate filler • Proactively flag risks, low stock, missed tasks, stalled projects ═══ GUARDRAILS ═══ • Never expose passwords, tokens, or credentials in chat • Never drop databases or delete production data without explicit confirmation • Rate limit: if same request in last 60s, acknowledge and skip • Group only — you are not available via DM (already enforced at code level) ═══ MEMORY ═══ [See injected memory below from previous sessions] {memory_context}

08 CLAUDE.md — Server Context

Auto-injected into every Claude session. Gives Claude full awareness of the Nanic server.

# CLAUDE.md — Nanic Server Context ## Server Identity - Host: 88.222.214.65 | OS: Ubuntu 22.04 - User: nanic | Workspace: /home/nanic - Role: This is the Nanic Ayurveda production server ## Running Docker Containers - nanic_frontend (6040→3000) → Nanic Ayurveda website frontend - nanic_backend (6030→4000) → Nanic backend API - nanic_postgres (6010→5432) → Main Nanic PostgreSQL DB - nanic_redis (6020→6379) → Nanic Redis cache - nanic_pgadmin (6050→80) → PGAdmin UI - nanic_dozzle (6060→8080) → Docker log viewer - nanic-bot-db (6070→5432) → This bot's PostgreSQL DB (new) - nanic-bot-docs (8898→80) → This plan site (nginx) - blood-frontend (5080→80) → Blood management frontend - blood-backend (5070→3000) → Blood management API - blood-postgres (5050→5432) → Blood DB - blood-redis (5060→6379) → Blood Redis - blood-pgadmin (5090→80) → Blood PGAdmin - nextcloud (4038→80) → Internal file storage - nextcloud-db (4039→5432) → Nextcloud DB - nextcloud-redis (4040→6379) → Nextcloud Redis - expense-bot (3050→3050) → Expense tracking bot (DO NOT MODIFY) - expense-web (3049→3049) → Expense web UI (DO NOT MODIFY) - gitea (3000→3000) → Internal Git server (SSH: 222→22) - jenkins (3001→8080) → CI/CD (agent: 50000) - nginx-proxy-manager (80/443→80/443, 127.0.0.1:81→81) → Reverse proxy ## Key Paths - /home/nanic/Projects/website/dev → Nanic website code - /home/nanic/Projects/BRMS → Business management system - /home/nanic/Projects/nginx → Nginx proxy manager - /home/nanic/Bot → THIS BOT ## How to Manage Static Sites 1. Place HTML in /home/nanic/Bot/docs/ 2. Access via bot-docs nginx on port 6085 3. Or use nginx-proxy-manager admin at localhost:81 to add domain routing ## How to Manage Docker - View logs: docker logs <name> -f --tail=100 - Restart: docker restart <name> - Rebuild: cd /home/nanic/Projects/<project> && docker compose up -d --build ## Business Context - Business: Nanic Ayurveda — Ayurvedic product brand - Products: Ashwagandha, Triphala, Giloy, Chyawanprash, Brahmi, Neem, Turmeric formulations - Operations: Online + wholesale, Instagram/social media presence - Inventory threshold alerts: < 20 units = restock needed

09 Security & Guardrails

Built-in at both the bot layer and the Claude prompt layer.

🔒
DM Blocking: Any message where chat.type == "private" is silently dropped at the handler level. No response, no error. Bots can't be abused via DMs.
⏱️
Rate Limiting: Max 5 messages per user per minute in the group. Beyond that, they get a "⏳ Slow down" reply. Prevents API abuse and runaway Claude calls.
🛡️
Destructive Operation Guard: Claude's system prompt instructs it to confirm before: dropping databases, deleting files, stopping production services, removing Docker volumes. One confirmation required.
🔑
Credential Safety: Claude is instructed never to output passwords, API keys, or tokens in the Telegram chat. Logs are sanitized before being shown.
Response Timeout: Claude subprocess has a 5-minute hard timeout. On timeout, user receives: "⚠️ That took too long. Try a simpler request or split it into parts."
🐳
Docker Access Scoping: Docker socket is mounted read-only by default. Write access (restart/rebuild) requires explicit enable in compose. Claude uses docker logs freely but pauses on destructive compose commands.
📝
Audit Log: Every message + Claude response is logged to PostgreSQL with timestamp, user_id, username, chat_id, cost. Full audit trail.

10 Deployment Architecture

Docker Compose with host networking for full server access. Three services: bot, db, docs.

services: # ─── Main Bot ──────────────────────────────────────────── bot: build: . container_name: nanic-ayurveda-bot restart: unless-stopped network_mode: host # Full server network — accesses all services volumes: - /home/nanic:/home/nanic # Full server workspace - /var/run/docker.sock:/var/run/docker.sock # Docker management - /home/nanic/.claude:/home/nanic/.claude # Claude auth + token refresh - bot_data:/app/data # Memory files + SQLite env_file: .env environment: HOME: /home/nanic WORKSPACE_DIR: /home/nanic depends_on: db: {condition: service_healthy} # ─── Bot Database ──────────────────────────────────────── db: image: postgres:16-alpine container_name: nanic-bot-db restart: unless-stopped ports: ["6070:5432"] environment: POSTGRES_DB: nanic_bot POSTGRES_USER: nanic_bot POSTGRES_PASSWORD: NanicBot@2026 volumes: [pgdata:/var/lib/postgresql/data] healthcheck: test: ["CMD-SHELL", "pg_isready -U nanic_bot"] interval: 5s; timeout: 5s; retries: 5 # ─── Plan / Docs Site ──────────────────────────────────── docs: image: nginx:alpine container_name: nanic-bot-docs restart: unless-stopped ports: ["6085:80"] volumes: [./docs:/usr/share/nginx/html:ro] volumes: pgdata: bot_data:

Environment Variables (.env)
TELEGRAM_BOT_TOKEN=8247821796:AAH...
TELEGRAM_GROUP_ID=-100xxxxxxxxx
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...
CLAUDE_MODEL=claude-sonnet-4-6
WORKSPACE_DIR=/home/nanic
DB_HOST=127.0.0.1
DB_PORT=6070
DB_NAME=nanic_bot
DB_USER=nanic_bot
DB_PASSWORD=NanicBot@2026
MORNING_BRIEF_HOUR=2
MORNING_BRIEF_MINUTE=0
SESSION_TIMEOUT_HOURS=8
RATE_LIMIT_PER_MINUTE=5
MAX_RESPONSE_TIMEOUT=300
Dockerfile
FROM python:3.11-slim

# Install Node.js 20 + Claude CLI
RUN curl -fsSL nodesource.com/setup_20.x | bash -
RUN apt-get install -y nodejs && npm install -g @anthropic-ai/claude-code

# Python deps
COPY requirements.txt .
RUN pip install -r requirements.txt

WORKDIR /app
COPY . .
RUN mkdir -p /app/data/memory
CMD ["python", "bot.py"]

11 Development Phases

Build in order. Each phase is independently deployable and testable.

1
Phase 1 — Core Bot (Foundation)
Get the bot talking with Claude in the group. Everything else builds on this.
  • Dockerfile + docker-compose.yml (bot + db + docs)
  • bot.py with group-only filter and DM blocking
  • claude/bridge.py — subprocess, stream-json collect, parse
  • "🤔 Thinking..." → response → "🔄 Refresh" (30s) flow
  • SQLite session management with --resume
  • db/database.py — asyncpg, create tables
  • Basic .env, CLAUDE.md, entrypoint.sh
2
Phase 2 — Memory & Context
Claude remembers things across sessions. Business knowledge accumulates over time.
  • memory/manager.py — MEMORY.md index + [REMEMBER] tag parsing
  • Top 5 relevant memories injected into every session prompt
  • Session expiry (8h) + context bridging on new session
  • claude/context.py — dynamic system prompt builder with time, user, memory
  • Log all messages + Claude responses to PostgreSQL (audit)
3
Phase 3 — Media & Commands
Handle images, documents. Add slash commands for power users.
  • utils/media.py — download photo/doc to /tmp/, tell Claude the path
  • handlers/group.py — photo handler, document handler
  • /status — show bot health, current session, memory count
  • /reset — clear current session (fresh context)
  • /memory — list recent memories saved by Claude
  • Message splitting for responses > 4096 chars
4
Phase 4 — Daily Briefing & Scheduler
Autonomous morning intelligence. Bot becomes proactive, not just reactive.
  • jobs/briefing.py — APScheduler job at 02:00 UTC (7:30 AM IST)
  • Claude checks Docker health, reads PostgreSQL revenue log, reads memory for tasks
  • Generates formatted morning brief + sends to GROUP_CHAT_ID
  • Revenue entry command: members can log sales (Claude parses, saves to DB)
  • Task tracking: "add task: restock Triphala" → Claude saves, appears in briefing
5
Phase 5 — Polish & Hardening
Production-ready. Rate limiting, error handling, monitoring.
  • Rate limiting (5 msgs/min per user) with graceful message
  • Claude token auto-refresh (check expiry before each call)
  • Graceful shutdown — finish current request before stopping
  • Error messages that are actually helpful to non-technical users
  • Optional: weekly revenue report on Sundays
  • Telegram group ID auto-detection (log first group message)

12 Complete Feature List

Everything the bot will do out of the box.

🤖 AI Responses
Answers anything: product advice, business decisions, Ayurveda knowledge, technical tasks, creative writing, planning. Claude Sonnet 4.6 with full tool access.
🖼️ Image Analysis
Send product photos, prescriptions, receipts, screenshots. Claude analyzes them via file path (downloads to /tmp). Works for OCR, quality checks, description generation.
🐳 Server Management
Ask "restart the frontend" or "show me backend logs" — Claude runs docker commands via --dangerously-skip-permissions on the mounted server.
🌐 Static Sites
Ask Claude to create a product page, landing page, or any HTML. It writes to /home/nanic/Bot/docs/ and it's live immediately at port 6085.
🌅 Daily Briefing
7:30 AM IST — revenue summary, Ayurveda business tip, today's tasks, server health. Fully automated every morning.
🧠 Persistent Memory
Claude remembers product prices, customer preferences, team decisions, anything it's told. Memory survives restarts. Grows smarter over time.
📋 Task Tracking
"Add task: update website pricing" → saved. Appears in next morning briefing. Mark done: "done: update website pricing."
💬 Group-Native
Responds to all messages in the group. Aware of who's talking (username context). DMs are completely ignored. No allowlist — entire group team can use it.
🔄 Refresh Button
Not happy with the response? Click 🔄 within 30 seconds to regenerate. Claude re-runs the same request with a fresh perspective.

Nanic Ayurveda Bot — Development Plan v1.0
Generated: April 18, 2026  |  Deployed: http://88.222.214.65:6085/plan.html