Pełna Specyfikacja Produktowa (PRD + Tech Spec) — dokument dla developera
Tutlo B2B Master to agent-first GTM (Go-To-Market) platforma, która zastępuje klasyczny dział sprzedaży B2B systemem 10 autonomicznych agentów AI z ludzkim nadzorem — od zimnego leadu do podpisanego kontraktu.
| Persona | Rola w systemie | Główna wartość |
|---|---|---|
| SDR / Handlowiec | Codzienny użytkownik | Gotowy plan dnia, spersonalizowane wiadomości, zero researchu |
| Sales Manager | Nadzór pipeline | Real-time widok pipeline, conversion rates, aktywność teamu |
| Marketing Manager | Content + trendy | LinkedIn Studio, trends intelligence, campaign performance |
| CEO (Damian) | Exec overview | Monthly board-ready raport, ROI, pipeline value |
Spersonalizowany briefing: "Cześć Piotr, dziś 8 zadań. 2 krytyczne (SLA), 3 follow-upy."
Real-time: "Firma X opublikowała ogłoszenie HR", "Decydent Y zmienił pracę", "Firma W otworzyła ofertę 3×"
➕ Dodaj firmę · 🎯 Stwórz kampanię · ✍️ Generuj post · 🔍 Zapytaj Copilota
Filtry: status (8), branża, wielkość, ostatni kontakt, handlowiec, score, region. Szybkie wyszukiwanie: NIP, nazwa, osoba.
Kolumny = statusy: Cold → Do kontaktu → W kontakcie → Demo umówione → Zainteresowany → Negocjacje → Aktywny klient → Niezainteresowany. Drag & drop zmienia status.
Zaznacz wiele → zmień status, przypisz handlowca, eksport CSV, dodaj do kampanii
Lista osób decyzyjnych cross-firm. Profil: stanowisko, LinkedIn, email, telefon, historia interakcji.
"Warm Signal" Badge: 🔥 Post o HR/L&D · 🔄 Zmiana pracy · 👍 Like postu Tutlo · 📢 Ogłoszenie o pracę
Per firma: "Generuj strategię" → AI output w formatce:
Historia strategii wersjonowana, diff view między wersjami.
Kanban: Do zrobienia → W toku → Zrobione. Zadania auto-generowane o 7:30 przez Daily Planner.
Per zadanie: firma, osoba, powód, sugerowana treść, priorytet (🔴/🟡/🟢), estymowany czas.
Actions: ✅ Zatwierdź · ✏️ Edytuj · ❌ Odrzuć. Filtr: moje / wszystkie / przeterminowane.
Wybierz osobę → AI generuje LinkedIn DM / email / call script → edytuj → wyślij
Multi-step: Day 0 connect → Day 1 DM → Day 4 email → Day 8 follow-up → Day 12 call. Stop na odpowiedź.
Zebrane odpowiedzi z LinkedIn + email w jednym miejscu. Quick reply z AI suggestion.
Generator: firma → AI tworzy ofertę (ROI calc, case study, cennik) → edit → wyślij z trackingiem.
Status: Wysłana → Otwarta → Negocjowana → Przyjęta ✅ / Odrzucona ❌
Alert: "Firma otworzyła ofertę 3× w godzinę" → sugestia call. PDF export + link tracking.
Per handlowiec: Tone of Voice setup → AI generuje 3 warianty postu → Approval Queue → Kalendarz → Publikacja
Formaty: Thought Leadership · Case Study · Hot Take · Behind the Scenes
Analytics: impressions, engagement, inbound DM, profile views delta
Feed: LinkedIn viral, YouTube (MFM, 30MPC), blogi, podcasty, Amazon bestsellery. Confidence score 0-100.
"Zaimplementuj" → agent tworzy action plan. Weekly brief (piątek). Knowledge base searchable.
| Rola | Uprawnienia |
|---|---|
| Admin | Pełny dostęp, zarządzanie użytkownikami, settings |
| Sales Manager | Pipeline all, raporty, approval |
| SDR | Własny pipeline, zadania, outreach |
| Marketing | LinkedIn Studio, Trends, Campaigns |
+ integracje API, agent AI settings (model, temperatura, prompt), statusy firm, szablony
Sygnał → Research Scout enrichuje → Lead Scorer update → ABM Strategy → Outreach Composer (sekwencja 5 kroków) → Handlowiec approve → Instantly/Waalaxy dispatch → Tracking → Odpowiedź = auto-pause + alert
Źródło (trend / case / kalendarz) → Content Agent generuje 3 warianty (ToV) → Approval Queue → Handlowiec edytuje → Kalendarz (wt/śr 8-10) → Publikacja → Tracking (impressions, inbound DM)
"Generuj ofertę" → Proposal Generator (ROI, case study, cennik) → Edit → Send z tracking link → Otwarta (alert) → 3× open = "Zadzwoń teraz" → Negocjacje → Przyjęta/Odrzucona → Status firmy auto-update
CREATE TABLE companies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
nip VARCHAR(10), krs VARCHAR(10),
industry TEXT, industry_category TEXT,
address TEXT, city TEXT, website TEXT, linkedin_url TEXT,
employee_count INTEGER, employee_range TEXT,
annual_revenue_pln BIGINT, founding_year INTEGER, logo_url TEXT,
-- Pipeline
status TEXT NOT NULL DEFAULT 'cold',
status_changed_at TIMESTAMPTZ,
assigned_to UUID REFERENCES users(id),
propensity_score INTEGER DEFAULT 0,
score_trend TEXT DEFAULT 'stable',
next_contact_date DATE, last_contact_date DATE,
-- Enrichment
enrichment_source TEXT, enriched_at TIMESTAMPTZ,
tech_stack TEXT[], buying_signals JSONB, job_postings JSONB,
-- Meta
notes TEXT, tags TEXT[],
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
created_by UUID REFERENCES users(id)
);
CREATE TABLE contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
first_name TEXT NOT NULL, last_name TEXT NOT NULL,
job_title TEXT,
role_priority TEXT DEFAULT 'tertiary',
email TEXT, email_verified BOOLEAN DEFAULT false,
phone TEXT, linkedin_url TEXT,
linkedin_last_activity TIMESTAMPTZ,
linkedin_last_post_topic TEXT,
warm_signals JSONB, apollo_id TEXT, notes TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE interactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID NOT NULL REFERENCES companies(id),
contact_id UUID REFERENCES contacts(id),
user_id UUID REFERENCES users(id),
type TEXT NOT NULL, -- linkedin_dm, email, call, meeting, note, demo
channel TEXT, direction TEXT DEFAULT 'outbound',
subject TEXT, content TEXT, response TEXT,
response_at TIMESTAMPTZ, sentiment TEXT,
source TEXT DEFAULT 'manual', metadata JSONB,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID REFERENCES companies(id),
contact_id UUID REFERENCES contacts(id),
assigned_to UUID NOT NULL REFERENCES users(id),
type TEXT NOT NULL, -- call, linkedin_dm, email, send_proposal
priority TEXT DEFAULT 'planned', -- critical, planned, optional
status TEXT DEFAULT 'todo', -- todo, in_progress, done, rejected
title TEXT NOT NULL, description TEXT,
suggested_content TEXT, trigger_reason TEXT,
due_date DATE, due_time TIME, estimated_minutes INTEGER,
completed_at TIMESTAMPTZ, rejection_reason TEXT,
source TEXT DEFAULT 'ai',
sequence_id UUID REFERENCES sequences(id),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE sequences (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID NOT NULL REFERENCES companies(id),
contact_id UUID REFERENCES contacts(id),
assigned_to UUID REFERENCES users(id),
name TEXT,
status TEXT DEFAULT 'draft', -- draft, active, paused, completed, stopped
channel_mix TEXT[],
started_at TIMESTAMPTZ, completed_at TIMESTAMPTZ,
stop_reason TEXT,
instantly_campaign_id TEXT, waalaxy_campaign_id TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE sequence_steps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
sequence_id UUID NOT NULL REFERENCES sequences(id) ON DELETE CASCADE,
step_number INTEGER NOT NULL,
channel TEXT NOT NULL, -- linkedin_connect, linkedin_dm, email, call
delay_days INTEGER DEFAULT 0,
subject TEXT, content TEXT NOT NULL,
status TEXT DEFAULT 'pending', -- pending, sent, opened, replied, bounced
sent_at TIMESTAMPTZ, opened_at TIMESTAMPTZ, replied_at TIMESTAMPTZ,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE proposals (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID NOT NULL REFERENCES companies(id),
contact_id UUID REFERENCES contacts(id),
created_by UUID REFERENCES users(id),
version INTEGER DEFAULT 1,
status TEXT DEFAULT 'draft', -- draft, sent, opened, negotiating, accepted, rejected
title TEXT, content JSONB, template_used TEXT,
pdf_url TEXT, tracking_link TEXT,
sent_at TIMESTAMPTZ, first_opened_at TIMESTAMPTZ,
last_opened_at TIMESTAMPTZ, open_count INTEGER DEFAULT 0,
total_view_seconds INTEGER DEFAULT 0,
accepted_at TIMESTAMPTZ, rejected_at TIMESTAMPTZ, rejection_reason TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE linkedin_posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
author_id UUID NOT NULL REFERENCES users(id),
status TEXT DEFAULT 'draft',
format TEXT, -- thought_leadership, case_study, hot_take, behind_scenes
topic TEXT, content TEXT NOT NULL, hashtags TEXT[],
scheduled_for TIMESTAMPTZ, published_at TIMESTAMPTZ,
approved_by UUID REFERENCES users(id), approved_at TIMESTAMPTZ,
impressions INTEGER, likes INTEGER, comments INTEGER, shares INTEGER,
profile_views_delta INTEGER, inbound_dms INTEGER,
linkedin_post_url TEXT, trend_id UUID REFERENCES trends(id),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE trends (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL, summary TEXT,
source_type TEXT, source_url TEXT, source_author TEXT,
category TEXT, relevance_score INTEGER,
actionable BOOLEAN DEFAULT false, suggested_action TEXT,
action_status TEXT DEFAULT 'new',
tags TEXT[], discovered_at TIMESTAMPTZ DEFAULT now(),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE ai_strategies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
company_id UUID NOT NULL REFERENCES companies(id),
version INTEGER DEFAULT 1,
status TEXT DEFAULT 'draft',
why_now TEXT, decision_makers JSONB,
hook TEXT, recommended_channel TEXT,
proposed_actions JSONB, confidence_score INTEGER,
trigger_type TEXT,
approved_by UUID REFERENCES users(id), approved_at TIMESTAMPTZ,
generated_by TEXT DEFAULT 'abm_strategy_generator',
created_at TIMESTAMPTZ DEFAULT now()
);
Rola: Enrichment — wzbogaca profil firmy danymi z internetu
Trigger: Nowa firma / request "Odśwież" / scheduled co 30 dni
Input: company.name, website, linkedin_url, nip
Output: employee_count, revenue, tech_stack, buying_signals, job_postings, kontakty
Model: Claude Sonnet 4 · Review: Brak (dane publiczne, auto-save)
Rola: Nadaje Propensity Score 0-100
Trigger: Po enrichmencie / zmiana sygnału / daily batch 7:00
Weights: Branża fit (+20), Wielkość (+25), Sygnały zakupowe (+15), LinkedIn aktywność (+10), Revenue growth (+10), Historia (+20)
Model: Claude Sonnet 4 + rules · Review: RevOps spot check weekly
Rola: Strategia dotarcia per firma
Trigger: Score > 60 / manual / nowy sygnał
Output: why_now, decision_makers, hook, channel, proposed_actions, confidence (1-10)
Model: Claude Opus 4 (deep reasoning) · Review: Handlowiec approve
Rola: Plan zadań na dzień per handlowiec
Trigger: Cron 7:30 CET (pon-pt)
Output: 8-12 tasks z priorytetem, briefem, suggested content
Model: Claude Sonnet 4 · Review: Handlowiec approve/reject
Rola: Spersonalizowane wiadomości i sekwencje
Trigger: Request / auto po ABM approve
Output: LinkedIn DM / email / call script / pełna sekwencja 5 kroków
Model: Claude Sonnet 4 · Review: Handlowiec approve każdą wiadomość
Rola: Spersonalizowane oferty z ROI calc
Trigger: Klik "Generuj ofertę"
Output: Oferta (dane firmy, plan, ROI, case study, cennik) + PDF
Model: Claude Opus 4 · Review: Handlowiec edytuje przed wysyłką
Rola: Posty LinkedIn per handlowiec
Trigger: Weekly batch (pon 8:00) / manual
Output: 3 warianty postu dopasowane do Tone of Voice
Model: Claude Sonnet 4 · Review: Handlowiec approve
Rola: 24/7 skanowanie źródeł + action plans
Trigger: Heartbeat 3×/dzień + weekly brief (piątek)
Sources: LinkedIn, YouTube (MFM, 30MPC), Sales Hacker, Amazon bestsellery
Model: Claude Sonnet 4 + Whisper · Review: Marketing Manager
Rola: Monitoring KPI + alerty anomalii
Trigger: Hourly + event-based (SLA breach)
Output: Alerty (dashboard + Slack), weekly exec summary
Model: Claude Sonnet 4 + SQL · Review: CRO weekly
Rola: Asystent UI — odpowiada na pytania o firmy, pipeline
Trigger: Chat query handlowca
Input: Query + RAG over Supabase (pgvector + SQL)
Model: Claude Sonnet 4 · Review: Brak (read-only)
Endpointy:
POST /v1/mixed_people/search — wyszukiwanie kontaktów po firmie, stanowiskuPOST /v1/organizations/enrich — enrichment firmyPOST /v1/people/match — weryfikacja emailiPobieramy: osoby decyzyjne (email, telefon, stanowisko, LinkedIn), dane firmy (employees, revenue, industry), intent signals
POST /api/v1/campaign/create — tworzenie kampaniiPOST /api/v1/campaign/add-leads — dodawanie leadówGET /api/v1/campaign/analytics — statystykiGET /api/v1/unibox/emails — inbox (odpowiedzi)Flow: Composer → create → add-leads → handlowiec approve → activate → poll analytics + unibox → sync Supabase
POST /api/campaigns, POST /api/campaigns/{id}/prospects, GET /api/inbox
Limity: max 50-80 connections/dzień, 50 DM/dzień per konto. Fallback: PhantomBuster.
Realtime: subscriptions na companies, tasks, proposals (live updates w UI)
Edge Functions: enrich-company, score-company, generate-daily-tasks (cron), track-proposal-open (webhook), sync-instantly-replies (cron 15min)
pgvector: embeddingi firm/strategii dla Copilot RAG
GET /crm/v3/objects/companies|contacts|deals + GET /engagements/v1/
Import do Supabase z flagą source: 'hubspot_import'. Potem read-only archive.
| Warstwa | Technologia | Uzasadnienie |
|---|---|---|
| Frontend | Next.js 15 + TS + Tailwind + Shadcn/ui | SSR, app router, component library |
| Backend/DB | Supabase (PG + Edge Functions + Realtime) | All-in-one, real-time, pgvector |
| AI | Claude Sonnet 4 + Opus 4 | Best reasoning, polski, cost-effective |
| Enrichment | Apollo.io + Research Scout agent | Apollo = kontakty, agent = custom |
| Instantly.ai | Deliverability, warmup, sequences | |
| Waalaxy | Safe automation, DM sequences | |
| Hosting | Vercel + Supabase Cloud | Zero-ops, auto-scaling |
| Auth | Supabase Auth (email + Google SSO) | Built-in, RBAC via RLS |
| Vector DB | pgvector (Supabase) | Copilot RAG, semantic search |
| Pozycja | Koszt/mies. |
|---|---|
| Supabase Pro | $25 |
| Vercel Pro | $20 |
| Apollo.io Professional | ~$500 |
| Instantly Growth | ~$100 |
| Waalaxy Business | ~$80 |
| Claude API (~500K tokens/dzień) | ~$300 |
| ŁĄCZNIE | ~$1,050/mies. (~4,200 PLN) |
Supabase setup, Next.js scaffold, import 5000 firm, HubSpot migration, Dashboard v0
DoD: Tabele + auth + 5000 firm + historia HubSpot + KPI tiles
Firmy (lista+Kanban+profil), Kontakty, Research Scout, Lead Scorer, Status taxonomy
DoD: CRUD firmy, drag-drop Kanban, top 500 enriched, scoring z breakdown
ABM Generator, Daily Planner (cron), Outreach Composer, Task Board, Outreach Center, Copilot
DoD: ABM < 2 min, 8-12 tasks/dzień, composer LinkedIn+email, Copilot RAG
Instantly + Waalaxy API, Proposal Generator, LinkedIn Studio, Trends Monitor, Analytics Sentry
DoD: Email campaigns via Instantly, LinkedIn DM via Waalaxy, oferty z trackingiem, posty zatwierdzane
Raporty, Settings, Inbox, Performance, Pilot 2 handlowców, Security audit
DoD: Exec PDF, settings panel, inbox unified, page load < 2s, pilot active
| KPI | Target 3 mies. | Target 6 mies. | Jak mierzymy |
|---|---|---|---|
| Handlowcy aktywni/tyg. | 80% | 95% | Login + ≥3 tasks/tyg. |
| AI approval rate | 70% | 85% | tasks approved / total |
| Demo leadów/mies. | 100-150 | 200-300 | status = demo_booked |
| Czas firma → demo | < 30 dni | < 14 dni | created_at → first demo |
| Response rate | 8-10% | 12-15% | steps replied / sent |
| LinkedIn reach/handlowiec | 2K imp. | 5K imp. | posts impressions/month |
| Nowe kontrakty/mies. | 15-20 | 30-45 | status → active_client |
| Koszt/demo lead | < 200 PLN | < 100 PLN | total cost / demo leads |
| # | Ryzyko | Impact | Mitygacja | Owner |
|---|---|---|---|---|
| 1 | Blokada LinkedIn — ban kont przy agresywnej automatyzacji | WYSOKI | 50 DM/dzień limit, rotacja kont, Sales Navigator, Content Studio = organic activity | SDR Lead |
| 2 | Jakość AI — wiadomości brzmią "jak AI" | ŚREDNI | Human-in-the-loop, ToV model, A/B testing, feedback loop | Product |
| 3 | Email deliverability — spam, spalona domena | WYSOKI | Dedykowane domeny, warmup 4-6 tyg., SPF/DKIM/DMARC, bounce < 2% | DevOps |
| 4 | RODO — scraping bez podstawy prawnej | WYSOKI | Konsultacja prawna, uzasadniony interes B2B, easy opt-out, log zgód | Legal |
| 5 | Adopcja team — handlowcy nie ufają AI | ŚREDNI | Pilot 2 champions, wyniki w 30 dni, szkolenie, incentive | Sales Mgr |