Sales operations
A useful daily log for agents. A clearer picture for managers.
It started with…
Agents record calls and administrative work. Managers follow campaigns and targets. They need the same figures, without asking everyone to enter the same activity twice.
So we built…
One workspace with a daily entry screen, a team dashboard and campaign views. Each starts from the same activity records and shared definitions.
Take a look inside
Screen 1 of 6Daily entry
An operational entry point for the current day.
What we set out to change
Make activity easier to report and help managers see the workload, missing reports and progress towards targets.
How it is builtData model, code, controls and team ownership
The user journey
- 01
Enter calls, outcomes and administrative activity for the day.
- 02
Allocate work to campaigns and correct past entries when needed.
- 03
Compare team progress with targets and inspect campaign workload.
Base structure
| Entity / table | Key fields | Relationships |
|---|---|---|
| Collaborators | Synced reference · Airtable account · service | One collaborator → daily logs, tasks and campaign allocations |
| Daily call log | Date · emitted calls · answered calls · outcomes | Daily activity connects to a collaborator |
| Campaigns & allocations | Stock · processed records · date · campaign link | Allocations connect a campaign to the daily work |
| Targets & task types | Target · scope · task category | Shared definitions support consistent reporting |
Technical implementation
- Table and field mappings are configurable; default resolution uses stable identifiers with name fallbacks.
- Period conversion rates are calculated from summed numerators and denominators.
- Campaign pace uses recent active days; business functions and their tests are separated from the interface.
Engineering decision
Forecast completion from actual activity days
Adapted from the campaign progress engine. It groups entries by activity date, uses the five most recent active days to estimate throughput, and compares a business-day projection with the deadline. Unknown stock remains unknown. This is a planning estimate, not a promised completion date; the calendar helper and input normalisation live in separate modules.
// Calendar helper from the delivery's date module.import { addBusinessDays } from "./dates.js";export function projectCampaign(campaign, entries, today) { const byDay = new Map(); let processed = 0; for (const entry of entries) { processed += entry.processed; if (entry.date) { byDay.set(entry.date, (byDay.get(entry.date) ?? 0) + entry.processed); } } const recentDays = [...byDay.keys()].sort().slice(-5); const velocity = recentDays.length ? recentDays.reduce((n, day) => n + byDay.get(day), 0) / recentDays.length : 0; const hasStock = campaign.volume > 0; const remaining = hasStock ? Math.max(0, campaign.volume - processed) : null; const projectedEnd = remaining > 0 && velocity > 0 ? addBusinessDays(today, remaining / velocity) : null; const overdue = remaining > 0 && campaign.deadline < today; return { processed, remaining, velocity, projectedEnd, late: overdue || Boolean(projectedEnd && projectedEnd > campaign.deadline), done: hasStock && remaining === 0, lastActivity: recentDays.at(-1) ?? null, };}Adapted implementation excerpt
Controls and boundaries
- Collaborator, Manager and Admin roles control the available screens. Airtable interface and data permissions must enforce access to records.
- A campaign forecast depends on the recorded activity and should be read as an estimate.
Who can contribute
- Agents: enter and correct their activity in the interface.
- Managers and builders: maintain campaigns, targets and task types in Airtable.
- Developers: change calculation rules in isolated modules with regression tests.
What supports this case
Daily entry, the team dashboard and campaign views were opened in Airtable; their data model and calculations are documented in the repository.