chore: add MVP planning backlog

This commit is contained in:
Matthias
2026-06-03 21:18:36 +02:00
parent a77d936a99
commit 762571cb43
27 changed files with 6420 additions and 117 deletions

15
backlog/config.yml Normal file
View File

@@ -0,0 +1,15 @@
project_name: "WebDev Pipeline"
default_status: "To Do"
statuses: ["To Do", "In Progress", "Done"]
labels: []
date_format: yyyy-mm-dd
max_column_width: 20
auto_open_browser: true
default_port: 6420
remote_operations: false
auto_commit: false
filesystem_only: true
bypass_git_hooks: false
check_active_branches: false
active_branch_days: 30
task_prefix: "task"

View File

@@ -0,0 +1,41 @@
---
id: TASK-1
title: Scaffold the Next.js MVP foundation
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- foundation
- nextjs
dependencies: []
references:
- PRD.md
priority: high
ordinal: 1000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Set up the application foundation for the WebDev Pipeline MVP: Next.js App Router, TypeScript, Tailwind, shadcn/ui, base routing, environment structure, and deployment-aware project conventions for Coolify. This task creates the technical base that all later feature work depends on.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Next.js App Router project exists with TypeScript and a working local dev script
- [ ] #2 Tailwind and shadcn/ui are configured and at least one shared UI component renders correctly
- [ ] #3 Base routes exist for dashboard, login placeholder, and public audit placeholder
- [ ] #4 Environment variable conventions are documented for Coolify, Convex, Google, OpenRouter, SMTP, and Rybbit
- [ ] #5 A basic smoke test or build command verifies the scaffold compiles
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Create or verify the Next.js App Router project structure.
2. Configure Tailwind, shadcn/ui, path aliases, and shared UI utilities.
3. Add base route groups for internal dashboard and public audit pages.
4. Add environment variable examples and keep all secrets out of source control.
5. Run the initial build/typecheck and record any setup notes.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-10
title: Build the local skills registry
status: To Do
assignee: []
created_date: '2026-06-03 19:13'
labels:
- mvp
- agent
- skills
dependencies:
- TASK-2
references:
- PRD.md
priority: high
ordinal: 10000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Create the local skills registry concept for the agent. Design and marketing skills are stored in the project repository and summarized in a skills.md registry so the agent can select relevant analysis and writing guidance for each audit while the dashboard shows which skills were used.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 A project-local skills directory or convention exists for imported design and marketing skills
- [ ] #2 skills.md lists each skill with name, purpose, when to use, when not to use, required input, expected output, and category
- [ ] #3 Agent code can load and parse the skills registry into structured skill metadata
- [ ] #4 Audit records store the list of used skills, including skill name/category and version or source where available
- [ ] #5 Dashboard audit detail shows a compact Verwendete Skills overview, but public audit pages do not
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define project-local skill storage conventions.
2. Create the initial skills.md registry format and seed entries for design, UX, marketing, copy, SEO, and offer-writing skills.
3. Add parser/loader for registry metadata.
4. Store selected skill metadata with each audit.
5. Show used skills in the internal audit detail UI only.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,44 @@
---
id: TASK-11
title: Create the OpenRouter AI audit pipeline
status: To Do
assignee: []
created_date: '2026-06-03 19:13'
labels:
- mvp
- agent
- llm
dependencies:
- TASK-8
- TASK-9
- TASK-10
references:
- PRD.md
priority: high
ordinal: 11000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Implement the LLM-powered audit generation pipeline using Vercel AI SDK and OpenRouter. The pipeline combines Google/Places data, Playwright crawl data, screenshots, PageSpeed signals, and local skills to generate structured internal findings plus final German audit, email, subject, call script, and follow-up drafts.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Vercel AI SDK is configured with OpenRouter and environment/Convex secrets
- [ ] #2 Model profiles exist for classification, multimodal audit analysis, German text generation, and final quality review
- [ ] #3 Structured audit outputs use Zod schemas and are stored in Convex with raw prompts/responses and model metadata
- [ ] #4 Screenshots can be passed to multimodal-capable models where supported
- [ ] #5 Generated customer-facing text follows Ich-Form, German language, no scores, no prices, no generic KI-Slop, and factual observation plus suggestion style
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add OpenRouter provider setup through Vercel AI SDK.
2. Define Zod schemas for internal findings, audit summary, email draft, subject, call script, follow-up, and quality review.
3. Build model-profile configuration for fast classification, multimodal analysis, and German copy generation.
4. Combine lead, crawl, screenshot, PageSpeed, and selected skills into prompt inputs.
5. Persist all prompts, model responses, normalized findings, final texts, and generation errors in Convex.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-12
title: Publish customer audit pages with manual approval
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- audit
- public-page
dependencies:
- TASK-11
references:
- PRD.md
priority: high
ordinal: 12000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Build the public customer-facing audit page system under the audit domain. Pages are generated from approved audit content, use clear human-readable slugs, show screenshots without annotations, avoid scores, include noindex, and remain hidden behind a neutral status message until manually approved.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Public audit pages render approved audit content with company name, domain, screenshots, observations, impact, suggestions, and final offer/CTA
- [ ] #2 Unapproved audit URLs show Dieser Audit ist noch nicht freigegeben without leaking company details
- [ ] #3 Deactivated audit URLs show a neutral unavailable message without exposing audit content
- [ ] #4 Audit pages are noindex, excluded from sitemap/public listing, and use a calm fixed light design
- [ ] #5 Approved pages are cached and cache is invalidated when the audit is edited and re-approved
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define public audit route and slug lookup rules.
2. Build the calm, fixed-light audit page layout with sections for context, observations, screenshots, suggestions, and CTA.
3. Add publication states for draft, approved/published, and deactivated.
4. Add noindex metadata and ensure audit routes are not listed in sitemap/navigation.
5. Add cache/revalidation behavior tied to approval and update actions.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,43 @@
---
id: TASK-13
title: Build the audit and outreach review workspace
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- review
- workflow
dependencies:
- TASK-11
- TASK-12
references:
- PRD.md
priority: high
ordinal: 13000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Create the internal review workspace where Matthias can inspect and edit the final audit summary, public audit link, email subject, email body, contact strategy, phone script, follow-up draft, sources, and used skills before any publication or sending happens.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Review workspace shows lead details, contact sources, priority reason, contact strategy, audit summary, used skills, and raw/source detail toggles
- [ ] #2 Audit content can be edited and manually approved before the public page shows customer-facing content
- [ ] #3 Email subject and body are editable and generated as exactly one recommended version by default
- [ ] #4 Phone script is available for Erst anrufen and Kontakt fehlt leads when a phone number exists
- [ ] #5 Freigabe offen state clearly separates Audit veröffentlichen from E-Mail freigeben und senden
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Build review route/detail UI with tabs for Audit, E-Mail, Telefon, Quellen, Rohdaten, and Skills.
2. Add edit forms for audit text, email subject/body, phone script, and follow-up.
3. Add approval actions for audit publication and separate email sending readiness.
4. Show source/contact confidence without exposing unnecessary raw noise by default.
5. Verify state transitions back into the Kanban/Funnel.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-14
title: Send approved outreach through Stalwart SMTP
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- email
- smtp
dependencies:
- TASK-13
references:
- PRD.md
priority: high
ordinal: 14000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Implement approved email sending through the self-hosted Stalwart mail server using SMTP/SMTPS and Nodemailer. The system must never send automatically before manual approval and must log recipient, subject, audit link, status, and errors in Convex.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Nodemailer is configured for Stalwart SMTP/SMTPS using environment or Convex secrets
- [ ] #2 E-Mail freigeben und senden sends only the currently approved/editable email draft to the visible recipient
- [ ] #3 A final send action shows recipient, subject, sender, and audit link before sending
- [ ] #4 Convex records sent timestamp, recipient, subject, audit link, SMTP result, and any error details
- [ ] #5 SMTP failures keep the lead in a retryable review state and do not mark the lead as contacted
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add SMTP transport configuration from secrets.
2. Add server-side send function that accepts only approved outreach IDs.
3. Add final confirmation UI with recipient, subject, sender, and audit link.
4. Store SMTP success/error outcomes and update lead/outreach status.
5. Test success and failure paths with safe non-production recipients before real use.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-15
title: Add follow-up and manual sales status tracking
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- sales
- follow-up
dependencies:
- TASK-14
references:
- PRD.md
priority: medium
ordinal: 15000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add the lightweight CRM layer needed after first contact. The MVP does not parse inbox replies automatically; Matthias manually marks responses and sales outcomes. Follow-ups are prepared by the agent and sent only after manual approval.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 After an initial send, a single follow-up draft and suggested due date are created
- [ ] #2 Follow-up sending requires manual review and approval, just like the first email
- [ ] #3 Manual statuses exist for Antwort erhalten, Kein Interesse, Später wieder melden, Gespräch vereinbart, Angebot angefragt, Angebot gesendet, Auftrag gewonnen, Auftrag verloren, Nicht weiter verfolgen, Follow-up geplant, and Follow-up gesendet
- [ ] #4 Marking Antwort erhalten or Kein Interesse stops pending follow-up prompts
- [ ] #5 Nicht erneut kontaktieren blocks outreach for 12 months and then reappears only as Erneut prüfen
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add follow-up fields and due-date logic to Outreach/Lead records.
2. Add manual status controls in lead detail and funnel cards.
3. Add follow-up review/send flow using the same SMTP approval boundaries.
4. Add rules to stop follow-ups when manually marked answered or not interested.
5. Add 12-month recheck behavior for Nicht erneut kontaktieren.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,44 @@
---
id: TASK-16
title: Orchestrate recurring Convex agent jobs and audit lifecycle
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- convex
- jobs
dependencies:
- TASK-6
- TASK-12
- TASK-15
references:
- PRD.md
priority: high
ordinal: 16000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Implement the scheduled and manual background workflow using Convex. The MVP permits only one active agent run at a time, supports campaign cron runs and manual Jetzt ausführen runs, and manages public audit lifecycle notifications and deactivation.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Convex cron or scheduled functions trigger active campaigns according to cadence
- [ ] #2 Jetzt ausführen starts a campaign run immediately only when no other agent run is active
- [ ] #3 Cron skips or queues safely when an agent run is already active, with visible run logs
- [ ] #4 Published audits older than 30 days create dashboard notifications asking whether to keep active
- [ ] #5 Published audits older than 60 days auto-deactivate unless manually extended or later reactivated
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add global agent-run lock or equivalent single-active-run guard.
2. Implement scheduled campaign runner using Convex cron/scheduling.
3. Wire manual Jetzt ausführen to the same runner and limits.
4. Add run logs and dashboard-visible status updates.
5. Add audit lifecycle checks for 30-day notification, 60-day deactivation, and reactivation.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-17
title: Add Rybbit audit analytics dashboard
status: To Do
assignee: []
created_date: '2026-06-03 19:14'
labels:
- mvp
- analytics
- rybbit
dependencies:
- TASK-12
references:
- PRD.md
priority: medium
ordinal: 17000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Display anonymous analytics for generated public audit pages inside the internal dashboard using the self-hosted Rybbit API. The internal dashboard itself is not tracked. Rybbit data is fetched per API on demand rather than regularly synchronized into Convex.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Rybbit tracking runs only on public audit pages, not on internal dashboard routes
- [ ] #2 Dashboard can fetch Rybbit API data for pageviews, custom events, and outbound link clicks for audit pages
- [ ] #3 Per-audit analytics show opened yes/no, view count, last view, CTA clicks, website-link clicks, and device type where available
- [ ] #4 Campaign analytics aggregate audit opens and CTA activity by campaign, niche, region, and timeframe
- [ ] #5 Rybbit API failures are shown gracefully and do not break the rest of the dashboard
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add Rybbit tracking snippet or event calls only to public audit pages.
2. Add server-side Rybbit API client using secrets.
3. Build per-audit analytics panel in the dashboard.
4. Build campaign-level analytics summaries.
5. Add graceful loading, caching if useful, and error states for API failures.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,45 @@
---
id: TASK-18
title: Add MVP quality gates and operational polish
status: To Do
assignee: []
created_date: '2026-06-03 19:15'
updated_date: '2026-06-03 19:15'
labels:
- mvp
- quality
- ops
dependencies:
- TASK-16
- TASK-17
- TASK-19
references:
- PRD.md
priority: medium
ordinal: 18000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add the final MVP quality layer: German UI consistency, i18n preparation, accessibility checks, run/error observability, secret hygiene, basic testing coverage, and deployment-readiness for Coolify. This task makes the MVP safe enough to use for real internal acquisition work.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Core UI text is German and organized so future i18n is feasible
- [ ] #2 No secrets are stored in source code, dashboard-editable records, logs, prompts, or raw LLM history
- [ ] #3 Dashboard surfaces integration errors for Google, PageSpeed, OpenRouter, Playwright, SMTP, Convex jobs, and Rybbit
- [ ] #4 Critical user flows have basic tests or repeatable verification notes: login, campaign run, audit generation, approval, send, follow-up, analytics
- [ ] #5 Coolify deployment notes cover required environment variables, Playwright browser dependencies, exposed port, and domain assumptions
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Audit UI copy for German consistency and avoid hard-to-localize scattered strings where practical.
2. Review secret handling and redact logs/prompts where needed.
3. Add integration status/error surfaces in dashboard run details.
4. Add smoke tests or documented verification flows for critical MVP paths.
5. Document Coolify deployment requirements, env vars, Playwright dependencies, and operational caveats.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,44 @@
---
id: TASK-19
title: Add campaign performance metrics
status: To Do
assignee: []
created_date: '2026-06-03 19:15'
labels:
- mvp
- analytics
- campaigns
dependencies:
- TASK-15
- TASK-16
- TASK-17
references:
- PRD.md
priority: medium
ordinal: 19000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Build the campaign metrics layer that summarizes acquisition progress from Convex data and enriches it with Rybbit audit signals. This is the practical reporting view Matthias uses to compare niches, regions, campaign runs, and outcomes.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Campaign dashboard shows found leads, leads with contact, Kontakt fehlt, audits created, approvals open, emails sent, follow-ups planned/sent, responses, conversations, offers, wins, and losses
- [ ] #2 Metrics can be filtered by campaign, niche/category, PLZ/region, radius, priority, status, and timeframe
- [ ] #3 Campaign run detail shows new leads, skipped duplicates, blacklisted/skipped leads, errors, and audits generated
- [ ] #4 Rybbit-derived audit opens and CTA clicks are shown alongside Convex sales funnel metrics
- [ ] #5 Metrics remain readable and lightweight, without becoming a full enterprise CRM dashboard
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define metric aggregation queries from campaigns, leads, audits, outreach, and run logs.
2. Add filters for campaign, category, region, timeframe, priority, and status.
3. Build campaign overview cards and run-detail tables.
4. Merge Rybbit API-derived audit activity into the visible analytics where available.
5. Add empty/error states and verify metrics update after lead, audit, send, and status changes.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-2
title: Wire Convex data and storage foundations
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- backend
- convex
dependencies:
- TASK-1
references:
- PRD.md
priority: high
ordinal: 2000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Configure Convex Cloud for the MVP and define the core persistence model for campaigns, leads, audits, outreach records, blacklist entries, run logs, and screenshot/file storage. The goal is a typed backend foundation that can support the dashboard, agent pipeline, and public audit pages.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Convex is connected to the Next.js app with generated types available
- [ ] #2 Core tables exist for campaigns, leads, audits, outreach, blacklist, run logs, and settings metadata
- [ ] #3 Convex File Storage is ready for desktop and mobile screenshots
- [ ] #4 Run-status and error-log concepts are represented so background jobs are observable
- [ ] #5 No API keys or secrets are stored in user-editable database records
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add Convex project configuration and connect it to the app.
2. Define schemas for Campaign, Lead, Audit, Outreach, BlacklistEntry, and AgentRun.
3. Add storage conventions for screenshot files and audit assets.
4. Add basic queries/mutations for creating and reading core records.
5. Verify Convex generation and typechecking work locally.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-3
title: Add Better Auth admin authentication
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- auth
- security
dependencies:
- TASK-2
references:
- PRD.md
priority: high
ordinal: 3000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add the MVP authentication layer using Better Auth with Convex integration. The MVP is single-user focused: one admin user protects the dashboard while public audit pages remain accessible without login according to their publication status.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Better Auth is integrated with Convex and the Next.js app
- [ ] #2 Email/password login protects all internal dashboard routes
- [ ] #3 Public audit routes remain accessible without dashboard authentication
- [ ] #4 Session handling survives refreshes and rejects unauthenticated dashboard access
- [ ] #5 Password-change or admin-account maintenance path is available or explicitly documented for MVP operation
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Install and configure Better Auth with Convex integration.
2. Add login/logout flows using shadcn-compatible UI.
3. Protect dashboard route groups with server-side/session checks.
4. Keep public audit pages outside the protected route boundary.
5. Test authenticated, unauthenticated, and logout flows.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-4
title: Build the dashboard shell and lead funnel
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- ui
- dashboard
dependencies:
- TASK-3
references:
- PRD.md
priority: high
ordinal: 4000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Create the internal German-language dashboard shell for the MVP. It should provide navigation, Light/Dark mode for the dashboard only, a Kanban/Funnel lead overview, status badges, and entry points into campaign, audit, review, analytics, and settings areas.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Dashboard shell has German navigation for campaigns, leads, audits, analytics, blacklist, and settings
- [ ] #2 Light/Dark theme toggle works only in the internal dashboard
- [ ] #3 Kanban/Funnel columns represent the agreed lead states, including Kontakt fehlt, Audit bereit, Freigabe offen, Kontaktiert, Follow-up, and Zurückgestellt
- [ ] #4 Lead cards show the key scan data: company, niche, location, priority, contact status, and next action
- [ ] #5 Dashboard remains keyboard accessible and responsive on practical desktop/tablet widths
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define dashboard route layout, sidebar, header, and content slots.
2. Add German navigation labels and status vocabulary.
3. Implement theme provider and dashboard-only toggle.
4. Build the Kanban/Funnel view using Convex lead data.
5. Add empty states, loading states, and basic accessibility checks.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-5
title: Implement campaign configuration and scheduling controls
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- campaigns
- forms
dependencies:
- TASK-4
references:
- PRD.md
priority: high
ordinal: 5000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Build the campaign management UI and backend mutations for reusable local search campaigns. Campaigns are configured with German postal code, radius, category or custom niche, run cadence, lead limits, audit limits, and active/paused state.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Campaign create/edit forms use React Hook Form, Zod, and shadcn form components
- [ ] #2 Campaigns support predefined categories plus Anderes with a required custom input
- [ ] #3 Campaigns store PLZ, radius, cadence, max new leads, max audits, active/paused state, and Germany-only context
- [ ] #4 Each campaign has a Jetzt ausführen action and shows last run, next run, and current run status
- [ ] #5 Form validation gives clear German error messages for invalid PLZ, radius, cadence, and limits
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define campaign Zod schemas and German validation messages.
2. Build campaign list, create, edit, pause, and resume UI.
3. Add Convex mutations/queries for campaign persistence.
4. Add run metadata fields for last run, next run, and current status.
5. Verify campaign forms and dashboard state transitions.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-6
title: Integrate Google Geocoding and Places lead discovery
status: To Do
assignee: []
created_date: '2026-06-03 19:12'
labels:
- mvp
- integrations
- leads
dependencies:
- TASK-5
references:
- PRD.md
priority: high
ordinal: 6000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Connect the campaign runner to Google Geocoding and Google Places. The system geocodes German postal codes, searches local businesses by category or custom niche within the configured radius, applies per-run limits, and stores source-backed lead records without sending outreach.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 German PLZ values are geocoded to coordinates and cached on the campaign or run
- [ ] #2 Google Places searches use category mappings or custom niche text plus configured radius
- [ ] #3 Lead records store Place ID, business name, address, category, website, phone, rating metadata for internal use, and source timestamps where available
- [ ] #4 Runs respect max new leads and never start if another agent run is already active
- [ ] #5 API failures, empty results, skipped duplicates, and skipped blacklisted entities are visible in run logs
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Define category-to-Places-query mappings for the initial MVP categories.
2. Add Google Geocoding integration with Germany-focused requests.
3. Add Google Places search integration using stored campaign settings.
4. Persist discovered leads with source metadata and run linkage.
5. Add run-level logging for success, empty, duplicate, blacklisted, and error cases.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-7
title: 'Add lead qualification, deduplication, and blacklist handling'
status: To Do
assignee: []
created_date: '2026-06-03 19:13'
labels:
- mvp
- leads
- quality
dependencies:
- TASK-6
references:
- PRD.md
priority: high
ordinal: 7000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Implement the rules that turn raw business discoveries into usable lead states. Leads should be classified by contact availability, website potential, duplicate risk, existing contact history, and manual blacklist matches before any audit or outreach work starts.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Leads with no usable email are placed in Kontakt fehlt while preserving phone and source data
- [ ] #2 Generic business emails are preferred and named emails are accepted only when explicitly found as business contact addresses
- [ ] #3 Hard duplicates are detected by domain, Google Place ID, or email; probable duplicates are flagged by name plus address or phone
- [ ] #4 Manual blacklist entries for domain, email, phone, company name, and Place ID are enforced during discovery and review
- [ ] #5 Priority values Hoch, Mittel, Niedrig, Zurückstellen, and Gesperrt are assigned or editable with clear reasons
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add blacklist CRUD in Convex and dashboard UI.
2. Implement email/contact extraction result fields and Kontakt fehlt transitions.
3. Add hard and probable duplicate matching rules.
4. Add priority assignment rules based on website/contact signals.
5. Surface reasons and source data in lead detail and run logs.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-8
title: Implement Playwright website crawling and screenshot capture
status: To Do
assignee: []
created_date: '2026-06-03 19:13'
labels:
- mvp
- audit
- playwright
dependencies:
- TASK-7
references:
- PRD.md
priority: high
ordinal: 8000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Build the website inspection layer using Playwright. For qualified leads, the system should load the company website, inspect the homepage and a small set of relevant subpages, capture desktop/mobile screenshots, extract visible text and contact signals, and store all raw evidence in Convex.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 Playwright captures desktop and mobile screenshots for the homepage and stores them in Convex File Storage
- [ ] #2 Crawler visits a bounded set of relevant subpages: Kontakt, Impressum, Leistungen/Angebot, Über uns/Team when discoverable
- [ ] #3 Crawler extracts visible text, page title, meta description, headings, links, phone numbers, email candidates, and CTA/contact-form signals
- [ ] #4 Simple technical checks include HTTPS/final URL, missing title/meta description, visible contact path, and obvious broken internal links within the crawl limit
- [ ] #5 Crawler failures produce useful dashboard-visible errors without blocking unrelated leads
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add Playwright runtime setup compatible with local development and Coolify container deployment.
2. Define crawl limits, viewports, timeout behavior, and allowed same-domain URL rules.
3. Capture homepage desktop/mobile screenshots and upload to Convex storage.
4. Discover and inspect relevant subpages with bounded depth.
5. Persist extracted text, metadata, contact candidates, technical checks, screenshots, and errors.
<!-- SECTION:PLAN:END -->

View File

@@ -0,0 +1,42 @@
---
id: TASK-9
title: Integrate PageSpeed Insights into internal audits
status: To Do
assignee: []
created_date: '2026-06-03 19:13'
labels:
- mvp
- audit
- pagespeed
dependencies:
- TASK-8
references:
- PRD.md
priority: medium
ordinal: 9000
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add Google PageSpeed Insights as an objective internal audit signal. The system should run mobile and desktop checks when possible, store raw results internally, and expose only plain-language implications to the later LLM/text pipeline rather than customer-facing scores.
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 PageSpeed API runs for mobile and desktop strategies for qualified website leads
- [ ] #2 Raw PageSpeed/Lighthouse response data is stored internally in Convex
- [ ] #3 Key metrics are normalized for downstream analysis without exposing scores on customer audit pages
- [ ] #4 Failures, quota errors, and unavailable pages are recorded without failing the entire audit pipeline
- [ ] #5 Generated audit inputs translate technical signals into customer-impact language for later text generation
<!-- AC:END -->
## Implementation Plan
<!-- SECTION:PLAN:BEGIN -->
1. Add PageSpeed API client using environment/Convex secrets.
2. Run mobile and desktop analysis for the lead domain or final URL.
3. Normalize key findings such as load speed, mobile/desktop gap, SEO, accessibility, and best-practice hints.
4. Store raw and normalized results in Convex.
5. Add error handling and dashboard-visible status for quota, timeout, and API failures.
<!-- SECTION:PLAN:END -->