Add multi-user features: i18n, payments, multi-model AI, focus areas

Replace single report type with composable analysis: depth levels
(basic/standard/full) + focus area multi-select (psychology, business,
marketing, content, audience, sentiment). Multi-step inline keyboard
flow guides users through selection.

- i18n: English + Russian, auto-detect from Telegram, /lang override
- AI providers: Anthropic + OpenRouter via AIClient abstraction
- Telegram Stars payments with per-depth pricing and free trial
- SQLite (aiosqlite) for users, analyses, payments tracking
- User middleware for auto-registration and language detection
- Report persistence: save .md locally, offer file download
- New commands: /features, /prices, /lang
- Composable prompt system: depth modifiers + focus area fragments
This commit is contained in:
Sergei Poljanski 2026-02-23 01:18:12 +02:00
commit c30b7e4675
27 changed files with 1155 additions and 280 deletions

View file

@ -1,27 +1,39 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
class ReportType(Enum):
CONTENT = "content"
CONTENT_STATS = "content_stats"
FULL_AUDIT = "full_audit"
class Depth(Enum):
BASIC = "basic"
STANDARD = "standard"
FULL = "full"
@property
def label(self) -> str:
return {
ReportType.CONTENT: "Content Analysis",
ReportType.CONTENT_STATS: "Content + Stats",
ReportType.FULL_AUDIT: "Full Audit",
Depth.BASIC: "Basic",
Depth.STANDARD: "Standard",
Depth.FULL: "Full",
}[self]
class FocusArea(Enum):
PSYCHOLOGY = "psychology"
BUSINESS = "business"
MARKETING = "marketing"
CONTENT = "content"
AUDIENCE = "audience"
SENTIMENT = "sentiment"
@property
def description(self) -> str:
def label(self) -> str:
return {
ReportType.CONTENT: "Topics, tone, themes, content strategy",
ReportType.CONTENT_STATS: "Above + posting frequency, engagement patterns",
ReportType.FULL_AUDIT: "All above + sentiment, audience insights, recommendations",
FocusArea.PSYCHOLOGY: "Psychology & Influence",
FocusArea.BUSINESS: "Business & Monetization",
FocusArea.MARKETING: "Marketing & Growth",
FocusArea.CONTENT: "Content Strategy",
FocusArea.AUDIENCE: "Audience & Engagement",
FocusArea.SENTIMENT: "Sentiment Analysis",
}[self]
@ -33,3 +45,11 @@ class ChannelMessage:
views: int | None = None
forwards: int | None = None
replies: int | None = None
@dataclass
class AnalysisSession:
channel: str
depth: Depth | None = None
focus_areas: list[FocusArea] = field(default_factory=list)
model_id: str | None = None