Moved out of studio/TODO.md (see #6).
contract renamed from counters to stats (campaign)
Problem
counters and stats are used inconsistently across the contract schemas.
packages/orpc/src/schema/projects.ts has both, and the split there is meaningful:
stats: z.object({ // engagement metrics
sent, bounced, opened, replied
}).optional(),
counters: z.object({ // entity counts
campaigns, leads, leadsLists
}).optional(),
packages/orpc/src/schema/campaigns.ts has a single counters object that mixes both concerns:
counters: z.object({
sent, opened, clicked, replied, bounced, unsubscribed, delivered, // metrics
leads, sequences, // entity counts
})
Proposal
Adopt the projects convention everywhere: stats = engagement metrics, counters = entity counts. On campaigns, split the current counters object into stats (sent/opened/clicked/replied/bounced/unsubscribed/delivered) and counters (leads/sequences).
Open question worth settling in this issue: campaigns_counters (contract + schema + API module, mounted at prefix /campaigns/counters) returns per-day engagement metrics — under the convention above it should be renamed to campaigns_stats / /campaigns/stats.
Scope
packages/orpc/src/schema/campaigns.ts, schema/campaigns_counters.ts
packages/orpc/src/contract/campaigns_counters.ts + its registration in contract/index.ts
apps/api/src/modules/campaigns/controller.ts, modules/campaigns/counters/*, modules/projects/controller.ts
apps/dashboard/src/enhancers/campaign.ts, components/campaigns/list/list.tsx, components/projects/list.tsx
- Rebuild
packages/orpc (+ dbschema if touched) afterwards.
Breaking change to the public route path if /campaigns/counters is renamed — fine while the API is still faker-backed and unreleased.
Moved out of
studio/TODO.md(see #6).Problem
countersandstatsare used inconsistently across the contract schemas.packages/orpc/src/schema/projects.tshas both, and the split there is meaningful:packages/orpc/src/schema/campaigns.tshas a singlecountersobject that mixes both concerns:Proposal
Adopt the projects convention everywhere:
stats= engagement metrics,counters= entity counts. Oncampaigns, split the currentcountersobject intostats(sent/opened/clicked/replied/bounced/unsubscribed/delivered) andcounters(leads/sequences).Open question worth settling in this issue:
campaigns_counters(contract + schema + API module, mounted at prefix/campaigns/counters) returns per-day engagement metrics — under the convention above it should be renamed tocampaigns_stats//campaigns/stats.Scope
packages/orpc/src/schema/campaigns.ts,schema/campaigns_counters.tspackages/orpc/src/contract/campaigns_counters.ts+ its registration incontract/index.tsapps/api/src/modules/campaigns/controller.ts,modules/campaigns/counters/*,modules/projects/controller.tsapps/dashboard/src/enhancers/campaign.ts,components/campaigns/list/list.tsx,components/projects/list.tsxpackages/orpc(+dbschemaif touched) afterwards.Breaking change to the public route path if
/campaigns/countersis renamed — fine while the API is still faker-backed and unreleased.