640f986967
Re-scoped Offer Editor (Tier A/B/C, Tag & Prezzo Pubblico) per 2026-06-14 user decision: 5-plan wave structure (schema migration -> prod apply checkpoint -> query/action layer -> list + detail editor UI), OFFER-12 CSV/Notion import deferred.
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>