fix(04): revision 1 — depends_on format + D-12 client list coverage
- 04-02/03/04: change depends_on from filename format to plan ID format
('04-01-PLAN.md' → '04-01') to match orchestrator expectations and
Phase 3 precedent
- 04-02: add Task 3 implementing D-12 — /admin/clients list shows brand
names below client name and LTV as sum of project accepted_totals;
update getAllClientsWithPayments query and ClientRow component;
add src/app/admin/page.tsx, src/lib/admin-queries.ts,
src/components/admin/ClientRow.tsx to files_modified
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ plan: "02"
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on:
|
||||
- 04-01-PLAN.md
|
||||
- "04-01"
|
||||
files_modified:
|
||||
- src/components/admin/NavBar.tsx
|
||||
- src/components/admin/ProjectRow.tsx
|
||||
@@ -12,6 +12,9 @@ files_modified:
|
||||
- src/app/admin/projects/new/page.tsx
|
||||
- src/app/admin/projects/project-actions.ts
|
||||
- src/app/admin/clients/[id]/page.tsx
|
||||
- src/app/admin/page.tsx
|
||||
- src/lib/admin-queries.ts
|
||||
- src/components/admin/ClientRow.tsx
|
||||
autonomous: true
|
||||
requirements:
|
||||
- PROJ-01
|
||||
@@ -25,6 +28,7 @@ must_haves:
|
||||
- "La pagina /admin/clients/[id] mostra cards dei progetti del cliente con bottone '+ Nuovo Progetto'"
|
||||
- "Cliccando una card progetto si naviga a /admin/projects/[id]"
|
||||
- "createProject e archiveProject sono server actions funzionanti"
|
||||
- "La lista /admin/clients mostra brand names dei progetti sotto il nome cliente e il Life Time Value (LTV = somma accepted_total di tutti i progetti del cliente) — D-12"
|
||||
artifacts:
|
||||
- path: "src/components/admin/NavBar.tsx"
|
||||
provides: "NavBar con link Progetti e Impostazioni"
|
||||
@@ -44,6 +48,9 @@ must_haves:
|
||||
- path: "src/app/admin/clients/[id]/page.tsx"
|
||||
provides: "Pagina cliente modificata per mostrare project cards"
|
||||
contains: "getClientWithProjects"
|
||||
- path: "src/app/admin/page.tsx"
|
||||
provides: "Lista clienti con brand names secondari e LTV colonna — D-12"
|
||||
contains: "getAllClientsWithPayments"
|
||||
key_links:
|
||||
- from: "src/app/admin/projects/page.tsx"
|
||||
to: "src/lib/admin-queries.ts"
|
||||
@@ -550,6 +557,101 @@ export default async function NewProjectPage({
|
||||
<done>/admin/projects funzionale con lista e form creazione; /admin/clients/[id] mostra project cards</done>
|
||||
</task>
|
||||
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: /admin/clients list — brand names secondari e LTV per cliente (D-12)</name>
|
||||
<files>
|
||||
src/app/admin/page.tsx
|
||||
src/lib/admin-queries.ts
|
||||
src/components/admin/ClientRow.tsx
|
||||
</files>
|
||||
|
||||
<read_first>
|
||||
- src/app/admin/page.tsx — leggere INTERAMENTE: struttura della lista clienti, ClientRow usage, tabella HTML
|
||||
- src/components/admin/ClientRow.tsx — leggere come viene mostrato il nome cliente e l'LTV attuale (accepted_total)
|
||||
- src/lib/admin-queries.ts — leggere getAllClientsWithPayments per capire il tipo corrente ClientWithPayments e la Promise.all interna
|
||||
</read_first>
|
||||
|
||||
<action>
|
||||
**A. Aggiornare getAllClientsWithPayments in src/lib/admin-queries.ts (D-12)**
|
||||
|
||||
La funzione deve restituire anche i brand names dei progetti e il LTV calcolato come somma degli accepted_total di tutti i progetti del cliente.
|
||||
|
||||
Estendere il tipo ClientWithPayments (o aggiungere nuovi campi inline) con:
|
||||
- `projectBrands: string[]` — nomi dei progetti non-archiviati del cliente, ordinati per created_at
|
||||
- `ltv: string` — somma degli accepted_total di TUTTI i progetti del cliente (inclusi archiviati)
|
||||
|
||||
Modificare getAllClientsWithPayments per aggiungere una query projects alla Promise.all esistente:
|
||||
|
||||
```typescript
|
||||
// Aggiungere alla Promise.all dentro getAllClientsWithPayments:
|
||||
db.select({
|
||||
client_id: projects.client_id,
|
||||
name: projects.name,
|
||||
accepted_total: projects.accepted_total,
|
||||
archived: projects.archived,
|
||||
})
|
||||
.from(projects)
|
||||
.where(inArray(projects.client_id, clientIds)),
|
||||
```
|
||||
|
||||
Nel map finale, aggiungere il calcolo:
|
||||
```typescript
|
||||
const clientProjects = allProjects.filter((p) => p.client_id === client.id);
|
||||
const projectBrands = clientProjects
|
||||
.filter((p) => !p.archived)
|
||||
.map((p) => p.name);
|
||||
const ltv = clientProjects
|
||||
.reduce((sum, p) => sum + parseFloat(p.accepted_total ?? "0"), 0)
|
||||
.toFixed(2);
|
||||
return {
|
||||
...existingClientObject,
|
||||
projectBrands,
|
||||
ltv,
|
||||
};
|
||||
```
|
||||
|
||||
Assicurarsi che `projects` sia importato da `@/db/schema` negli import esistenti (da 04-01 è già presente).
|
||||
|
||||
**B. Aggiornare src/components/admin/ClientRow.tsx — brand names + LTV colonna (D-12)**
|
||||
|
||||
Leggere ClientRow.tsx interamente. Aggiungere:
|
||||
|
||||
1. Sotto il nome cliente in bold, aggiungere la riga brand secondaria:
|
||||
```tsx
|
||||
{client.projectBrands && client.projectBrands.length > 0 && (
|
||||
<p className="text-xs text-[#71717a] mt-0.5">
|
||||
{client.projectBrands.join(" | ")}
|
||||
</p>
|
||||
)}
|
||||
```
|
||||
|
||||
2. Per la colonna LTV: sostituire `client.accepted_total` con `client.ltv` (che è ora la somma dei progetti). Se la colonna LTV non esiste ancora, aggiungere una colonna con `€{parseFloat(client.ltv).toLocaleString("it-IT", { minimumFractionDigits: 2 })}`.
|
||||
|
||||
3. Aggiornare il tipo prop di ClientRow per includere i nuovi campi:
|
||||
```typescript
|
||||
// Aggiungere ai campi di ClientWithPayments usati da ClientRow:
|
||||
projectBrands: string[];
|
||||
ltv: string;
|
||||
```
|
||||
|
||||
Se ClientRow usa `ClientWithPayments` importato da admin-queries, il tipo sarà aggiornato automaticamente dalla modifica in A. Verificare che TypeScript non si lamenti.
|
||||
</action>
|
||||
|
||||
<verify>
|
||||
<automated>npm run build 2>&1 | tail -20</automated>
|
||||
</verify>
|
||||
|
||||
<acceptance_criteria>
|
||||
- src/lib/admin-queries.ts contains `projectBrands` (grep: `grep "projectBrands" src/lib/admin-queries.ts`)
|
||||
- src/components/admin/ClientRow.tsx contains `projectBrands.join` (grep)
|
||||
- src/components/admin/ClientRow.tsx contains `client.ltv` (grep)
|
||||
- `npm run build` completa senza errori TypeScript
|
||||
- Visitando /admin ogni riga cliente mostra i brand names sotto il nome (es. "Brand Blu | Brand Verde") e la colonna LTV mostra la somma degli accepted_total di tutti i progetti
|
||||
</acceptance_criteria>
|
||||
|
||||
<done>Lista /admin/clients mostra brand names secondari sotto nome cliente e LTV calcolato come somma dei progetti — D-12 implementato</done>
|
||||
</task>
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
Reference in New Issue
Block a user