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
|
type: execute
|
||||||
wave: 2
|
wave: 2
|
||||||
depends_on:
|
depends_on:
|
||||||
- 04-01-PLAN.md
|
- "04-01"
|
||||||
files_modified:
|
files_modified:
|
||||||
- src/components/admin/NavBar.tsx
|
- src/components/admin/NavBar.tsx
|
||||||
- src/components/admin/ProjectRow.tsx
|
- src/components/admin/ProjectRow.tsx
|
||||||
@@ -12,6 +12,9 @@ files_modified:
|
|||||||
- src/app/admin/projects/new/page.tsx
|
- src/app/admin/projects/new/page.tsx
|
||||||
- src/app/admin/projects/project-actions.ts
|
- src/app/admin/projects/project-actions.ts
|
||||||
- src/app/admin/clients/[id]/page.tsx
|
- src/app/admin/clients/[id]/page.tsx
|
||||||
|
- src/app/admin/page.tsx
|
||||||
|
- src/lib/admin-queries.ts
|
||||||
|
- src/components/admin/ClientRow.tsx
|
||||||
autonomous: true
|
autonomous: true
|
||||||
requirements:
|
requirements:
|
||||||
- PROJ-01
|
- PROJ-01
|
||||||
@@ -25,6 +28,7 @@ must_haves:
|
|||||||
- "La pagina /admin/clients/[id] mostra cards dei progetti del cliente con bottone '+ Nuovo Progetto'"
|
- "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]"
|
- "Cliccando una card progetto si naviga a /admin/projects/[id]"
|
||||||
- "createProject e archiveProject sono server actions funzionanti"
|
- "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:
|
artifacts:
|
||||||
- path: "src/components/admin/NavBar.tsx"
|
- path: "src/components/admin/NavBar.tsx"
|
||||||
provides: "NavBar con link Progetti e Impostazioni"
|
provides: "NavBar con link Progetti e Impostazioni"
|
||||||
@@ -44,6 +48,9 @@ must_haves:
|
|||||||
- path: "src/app/admin/clients/[id]/page.tsx"
|
- path: "src/app/admin/clients/[id]/page.tsx"
|
||||||
provides: "Pagina cliente modificata per mostrare project cards"
|
provides: "Pagina cliente modificata per mostrare project cards"
|
||||||
contains: "getClientWithProjects"
|
contains: "getClientWithProjects"
|
||||||
|
- path: "src/app/admin/page.tsx"
|
||||||
|
provides: "Lista clienti con brand names secondari e LTV colonna — D-12"
|
||||||
|
contains: "getAllClientsWithPayments"
|
||||||
key_links:
|
key_links:
|
||||||
- from: "src/app/admin/projects/page.tsx"
|
- from: "src/app/admin/projects/page.tsx"
|
||||||
to: "src/lib/admin-queries.ts"
|
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>
|
<done>/admin/projects funzionale con lista e form creazione; /admin/clients/[id] mostra project cards</done>
|
||||||
</task>
|
</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>
|
</tasks>
|
||||||
|
|
||||||
<threat_model>
|
<threat_model>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ plan: "03"
|
|||||||
type: execute
|
type: execute
|
||||||
wave: 2
|
wave: 2
|
||||||
depends_on:
|
depends_on:
|
||||||
- 04-01-PLAN.md
|
- "04-01"
|
||||||
files_modified:
|
files_modified:
|
||||||
- src/app/admin/projects/[id]/page.tsx
|
- src/app/admin/projects/[id]/page.tsx
|
||||||
- src/app/admin/timer-actions.ts
|
- src/app/admin/timer-actions.ts
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ plan: "04"
|
|||||||
type: execute
|
type: execute
|
||||||
wave: 3
|
wave: 3
|
||||||
depends_on:
|
depends_on:
|
||||||
- 04-02-PLAN.md
|
- "04-02"
|
||||||
- 04-03-PLAN.md
|
- "04-03"
|
||||||
files_modified:
|
files_modified:
|
||||||
- src/app/api/internal/validate-slug/route.ts
|
- src/app/api/internal/validate-slug/route.ts
|
||||||
- src/proxy.ts
|
- src/proxy.ts
|
||||||
|
|||||||
Reference in New Issue
Block a user