f7eb7eec23
.planning/ documentava in dettaglio cio che era vecchio e per niente cio
che e in produzione: le fasi 11-22 (v2.1 e v2.2, chiuse a giugno) erano
ancora in phases/ mentre v1.0 e v2.0 stavano gia in milestones/, e il
lavoro degli ultimi due mesi - gate OTP e ciclo di vita dei retainer, cioe
quello che gira su hub.iamcavalli.net - non aveva nessuna cartella.
- phases/{11,12,14} -> milestones/v2.1-phases/, phases/{18..22} ->
milestones/v2.2-phases/. Ora phases/ contiene solo la milestone in
corso, che e quello che state.cjs conta per il progresso
- v2.1-ROADMAP.md ricostruito: era l'unica milestone senza archivio,
interrotta dal reset del 19/06 e mai chiusa formalmente
- v2.3-ROADMAP.md + v2.3-REQUIREMENTS.md: v2.3 e stata eseguita fuori dal
ciclo GSD, non esistono PLAN/SUMMARY per fase. L'archivio E la doc
- REQUIREMENTS.md riscritto per v2.4 con il backlog reale
- phases/13 e phases/26: SUMMARY ricostruiti da commit, migration e
STATUS.md. 26 e il primo numero libero
- research/: cancellate 4 varianti dello stesso PITFALLS e FEATURES/
SUMMARY, superati da PROJECT.md. Diverse anti-feature erano ormai
contraddette dai fatti (il Kanban e stato costruito in Phase 19,
l'email in v2.3, il time tracking esiste)
- cancellati UI-RULES.md e DESIGN-SYSTEM.md (CLAUDE.md li dichiara
superseded: impongono l'inverso della regola attuale) e HANDOFF.md,
fermo al 13/06
- SECURITY-*.md -> security/: audit chiuso, ma i report restano la doc di
cosa e stato ruotato e perche
- PROJECT.md/MILESTONES.md/ROADMAP.md allineati: milestone corrente v2.4,
sessione OTP 90gg non 30, migrazioni fino alla 0016
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.5 KiB
6.5 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 12 | 02 | execute | 2 |
|
false |
|
|
Purpose: Unblock Wave 2/3 schema-dependent code per the project's locked migration convention
(migrations applied to prod before schema-dependent code ships).
Output: Migration 0008 applied to production; confirmation that offer_tier_services exists
and the new columns are queryable on the live DB.
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/STATE.md @scripts/push-12-offer-tier-schema.ts @src/db/migrations/0008_offer_tier_schema.sql Task 1: Apply migration 0008 to production database Plan 01 created `src/db/migrations/0008_offer_tier_schema.sql` (additive-only: 11 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` statements on `offer_macros`/`offer_micros`, a guarded `CHECK` constraint on `offer_micros.tier_letter`, and `CREATE TABLE IF NOT EXISTS offer_tier_services` + index) and the idempotent push script `scripts/push-12-offer-tier-schema.ts` that applies it.This script CANNOT be run from this environment: the production DATABASE_URL
(`178.104.27.55:54321`) is firewalled and reachable only via SSH to the production host
(per `project_clienthub_deploy_db.md`). Opening a root SSH session to the shared
production host is outside this agent's authorization.
On your machine (or via your existing SSH access to the production host), run the
migration push script against the production database, then confirm the new schema
objects exist:
1. SSH to the production host and exec into the Postgres container (same pattern used
for the Phase 11 migration apply):
```bash
ssh root@178.104.27.55
docker exec -it <postgres-container-name> psql -U clienthub -d clienthub
```
OR, if you prefer running the idempotent TypeScript push script with
`DATABASE_URL` pointed at prod (via SSH port-forward / tunnel, same as Phase 11):
```bash
npx tsx scripts/push-12-offer-tier-schema.ts
```
2. If using `psql` directly, run the contents of
`src/db/migrations/0008_offer_tier_schema.sql` (copy/paste — it is additive-only and
idempotent, safe to run even if partially applied already).
3. Confirm the new columns and table exist:
```sql
\d offer_macros
\d offer_micros
\d offer_tier_services
```
Expect: `offer_macros` has `description`, `category`, `ticket`, `is_archived`,
`cliente_ideale`, `risultato`, `tempo`, `pain`, `metodo`; `offer_micros` has
`tier_letter` (with a CHECK constraint `offer_micros_tier_letter_check`) and
`public_price`; `offer_tier_services` table exists with columns `tier_id`,
`service_id`, `created_at` and a composite primary key on (`tier_id`, `service_id`).
4. Confirm no existing data was affected:
```sql
SELECT count(*) FROM offer_macros;
SELECT count(*) FROM offer_micros;
SELECT count(*) FROM clients;
SELECT count(*) FROM projects;
```
Row counts should match pre-migration counts (migration is additive — no rows
deleted).
Type "applied" once migration 0008 has been run against production and you've confirmed the new columns/table exist (or describe any errors encountered).
<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| Operator (human) -> Production Postgres | Manual SSH+docker exec session per project convention; only additive, idempotent SQL from migration 0008 is executed |
STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|---|---|---|---|---|
| T-12-05 | Denial of Service / Tampering | Manual prod migration apply | accept | Operator runs only the additive, idempotent migration 0008 (already grep-gated in Plan 01 against DROP/TRUNCATE/RENAME); per project convention this is a manual, out-of-band step not reachable via any HTTP endpoint |
| </threat_model> |
<success_criteria>
- Migration 0008 is live on production.
offer_tier_servicestable and all newoffer_macros/offer_microscolumns are queryable on prod.- No row in
clients,projects,payments,phases,offer_macros, oroffer_microswas deleted or modified destructively. </success_criteria>