Преминете към основното съдържание

Потребителско пътуване

Този документ описва пълното пътуване на потребителя от момента на откриване на Dictaro до ежедневна употреба и управление на абонамент.

Обзор на етапите

1. Откриване

Потребителите научават за Dictaro по няколко канала:

КаналОписание
Уебсайтdictaro.ai — Astro сайт на Cloudflare Pages
Microsoft StoreMSIX пакет, публикуван в Windows Store
Социални мрежиProduct Hunt, Reddit, Hacker News, Twitter/X
ПрепоръкиWord of mouth от съществуващи потребители

2. Изтегляне и инсталация

  • MSIX пакет — стандартен Windows инсталационен формат
  • Поддържа автоматични актуализации чрез Microsoft Store
  • Директното изтегляне е достъпно от уебсайта

3. Първо стартиране — безплатна употреба без акаунт

При първото стартиране приложението работи в анонимен режим — не е необходима регистрация.

Ключови характеристики на анонимния режим:

  • Квота: 10 минути диктовка (QUOTA_MINUTES=10)
  • При изчерпване: 5 часа cooldown (COOLDOWN_HOURS=5)
  • Устройството се идентифицира чрез уникален device_id
  • Usage записите се съхраняват с user_id = NULL
  • Поддържа офлайн кеширане на записи (UsageCache) за синхронизиране при възстановяване на връзката

4. Регистрация

Device limit проверка (само за free потребители):

  • Максимум DEVICE_ACCOUNTS_MAX=2 различни акаунта на устройство
  • В рамките на cooldown прозорец от COOLDOWN_HOURS=5 часа
  • Pro потребителите не са ограничени

Миграция на анонимни записи: При регистрация, функцията MigrateDeviceToUser свързва всички анонимни usage записи от устройството с новия потребител (UPDATE usage_records SET user_id=$1 WHERE device_id=$2 AND user_id IS NULL).

5. Пробен период (Trial)

  • Продължителност: TRIAL_DAYS=7 дни
  • Старт: Автоматично при първо записване на usage (trial_started_at се записва в DB)
  • Достъп: Неограничена диктовка по време на trial (статус "trial")
  • Край: Автоматичен преход към free план с квота 10 мин/cooldown 5ч

6. Ежедневна употреба

Работен процес на диктовка

Клиентска логика (Rust):

  • UsageManager управлява quota status и usage записи
  • Асинхронни HTTP заявки чрез tokio runtime
  • can_dictate() проверява дали статусът е "active", "unlimited" или "trial"
  • should_warn() показва предупреждение при 75% изразходвана квота
  • cooldown_display() форматира оставащото време до края на cooldown

Офлайн поддръжка

7. Изчерпване на квотата

Алгоритъм на rolling quota (walkCycles):

  1. Обхождат се всички usage записи хронологично
  2. Натрупва се cycleSum — общо използвани секунди
  3. Когато cycleSum >= quotaSeconds → cooldown започва
  4. Записи по време на cooldown се пропускат
  5. След края на cooldown → cycleSum се нулира, нов цикъл

Показване на cooldown в клиента:

  • cooldown_display() показва часа на край (напр. "17:00")
  • Диктовката е блокирана (can_dictate() връща false)

8. Upgrade към Pro

Поддържани интервали:

  • monthly — месечен абонамент
  • annual / yearly / year — годишен абонамент

Промоционални кодове: Активирани чрез AllowPromotionCodes: true в Stripe Checkout Session.

9. Pro употреба

Pro функции:

  • Неограничена диктовка — статус "unlimited", без квота и cooldown
  • AI text cleanup — LLM post-processing с BYOK модел (OpenAI / Claude API key)
  • Professional tone mode — формализиране на текста
  • Reformulation mode — преструктуриране на изречения
  • Grammar correction — граматична корекция
  • CLI transcription — транскрипция от командния ред
  • Fair use лимит: до 720 часа/месец

Typing ratio:

  • TYPING_RATIO=4.0 — всяка секунда диктовка спестява 4 секунди въвеждане
  • Използва се за показване на total_typing_saved_seconds в статистиките

10. Управление на абонамент

Stripe Customer Portal:

  • Достъпен чрез POST /account/portal-url
  • Изисква stripe_customer_id в потребителския запис
  • Потребителят може самостоятелно да управлява абонамента
  • Return URL: /billing/portal-return

Account status endpoint (GET /account/status):

  • Показва текущ план, email, име
  • Показва последните 4 символа на лицензния ключ (ако има)
  • Показва subscription_expiry ако абонаментът е маркиран за отказ (cancel_at_period_end)

Пълна диаграма на състоянията