Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions apps/api/drizzle/0061_retire_solutions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
-- Retire solutions per DEC-20260503-A 2026-05-04. Public surface gone;
-- composition tech (lib/solution-executor.ts, gate4b-solution-dryrun.ts,
-- validateSolution) retained for any future bundled-product module.
--
-- Strategy: archive both tables into _archived_2026_05_04 sibling tables
-- (preserves every column + adds archived_at), then truncate the live
-- tables. CASCADE on TRUNCATE solutions handles solution_steps via the
-- existing FK ON DELETE CASCADE, but archiving solution_steps separately
-- means the archive captures the full state independently of cascade
-- semantics.
--
-- Schemas of the live `solutions` and `solution_steps` tables are RETAINED
-- because internal admin/debug routes (/v1/internal/trust/solutions/*,
-- /v1/internal/tests/solutions/*, /v1/internal/quality/solutions/*,
-- /v1/admin/create-solution, etc.) still reference them. Drop the schemas
-- in a future migration once those routes are also retired.
--
-- Reversibility:
-- INSERT INTO solutions SELECT id, slug, name, description, long_description,
-- agent_description, category, price_cents, component_sum_cents, value_tier,
-- maintenance_level, geography, input_schema, example_input, example_output,
-- target_audience, marketing_name, transparency_tag, extends_with,
-- compliance_coverage, is_active, display_order, search_tags, x402_enabled,
-- created_at, updated_at FROM solutions_archived_2026_05_04;
-- INSERT INTO solution_steps SELECT id, solution_id, capability_slug, step_order,
-- can_parallel, parallel_group, input_map, created_at
-- FROM solution_steps_archived_2026_05_04;

-- 1. Archive solutions rows (115 rows expected; pre-flight 2026-05-04).
CREATE TABLE IF NOT EXISTS solutions_archived_2026_05_04 AS
SELECT *, NOW() AS archived_at FROM solutions;

-- 2. Archive solution_steps rows (892 rows expected; pre-flight 2026-05-04).
CREATE TABLE IF NOT EXISTS solution_steps_archived_2026_05_04 AS
SELECT *, NOW() AS archived_at FROM solution_steps;

-- 3. Truncate live tables. CASCADE drops solution_steps rows via the
-- existing solution_steps.solution_id ON DELETE CASCADE FK, but listing
-- both explicitly keeps intent obvious.
TRUNCATE TABLE solutions CASCADE;
TRUNCATE TABLE solution_steps;
22 changes: 22 additions & 0 deletions apps/api/scripts/apply-migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ async function main() {
console.log("[migration] actual_cost_cents already exists — skipping");
}

// Migration 0061: archive + truncate solutions + solution_steps per
// DEC-20260503-A. Idempotent because the archive tables use IF NOT
// EXISTS, the source tables are TRUNCATEd unconditionally each run,
// and a second run finds the live tables already empty (no-op).
// After archive tables exist on first run, future runs skip the
// CREATE TABLE AS step (no clobber) but still re-TRUNCATE — fine
// because the schema's intended steady state is empty live tables.
console.log("[migration] Ensuring solutions archive + truncate (DEC-20260503-A)...");
await db.execute(sql`
CREATE TABLE IF NOT EXISTS solutions_archived_2026_05_04 AS
SELECT *, NOW() AS archived_at FROM solutions
`);
await db.execute(sql`
CREATE TABLE IF NOT EXISTS solution_steps_archived_2026_05_04 AS
SELECT *, NOW() AS archived_at FROM solution_steps
`);
// TRUNCATE both. Using two statements keeps intent explicit; CASCADE
// on solutions handles the FK to solution_steps either way.
await db.execute(sql`TRUNCATE TABLE solutions CASCADE`);
await db.execute(sql`TRUNCATE TABLE solution_steps`);
console.log("[migration] solutions retired (archived + truncated)");

console.log("[migration] All migrations applied");
process.exit(0);
}
Expand Down
1 change: 0 additions & 1 deletion apps/api/scripts/console-allowlist.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"apps/api/src/db/generate-tests.ts": 13,
"apps/api/src/db/manual-test-rerun.ts": 14,
"apps/api/src/db/seed-limitations.ts": 4,
"apps/api/src/db/seed-solutions.ts": 9,
"apps/api/src/db/seed-tests.ts": 8,
"apps/api/src/db/verify-dual-profile.ts": 15,
"apps/api/src/diagnostics/self-heal-check.ts": 2,
Expand Down
15 changes: 3 additions & 12 deletions apps/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ import { agentCardRoute, a2aRoute } from "./routes/a2a.js";
import { adminRoute } from "./routes/admin.js";
import { solutionsRoute } from "./routes/solutions.js";
import { solutionExecuteRoute } from "./routes/solution-execute.js";
import { web3AssuranceRoute } from "./web3-assurance/routes.js";
import {
methodologyRoute as web3AssuranceMethodologyRoute,
sourceQualityRoute as web3AssuranceSourceQualityRoute,
bridgeConfigIndexRoute as web3AssuranceBridgeConfigIndexRoute,
} from "./web3-assurance/methodology.js";
import { trustIndexRoute as web3AssuranceTrustIndexRoute } from "./web3-assurance/trust-index.js";
import { qualityRoute } from "./routes/quality.js";
import { suggestRoute } from "./routes/suggest.js";
import { internalQualityRoute } from "./routes/internal-quality.js";
Expand Down Expand Up @@ -281,13 +274,11 @@ app.post(
);
app.route("/v1/demand-signals", demandSignalsRoute);
app.route("/v1/admin", adminRoute);
// Solutions surface retired DEC-20260503-A 2026-05-04. Routes return 410 Gone;
// full handler removal is phase 1b. Web3 Assurance code deleted in lockstep
// (chat 2026-05-04) — its routes are unregistered entirely.
app.route("/v1/solutions", solutionsRoute);
app.route("/v1/solutions", solutionExecuteRoute);
app.route("/v1/web3-assurance", web3AssuranceRoute);
app.route("/v1/web3-assurance/methodology", web3AssuranceMethodologyRoute);
app.route("/v1/web3-assurance/source-quality", web3AssuranceSourceQualityRoute);
app.route("/v1/web3-assurance/bridge-config-index", web3AssuranceBridgeConfigIndexRoute);
app.route("/v1/web3-assurance/trust-index", web3AssuranceTrustIndexRoute);
app.route("/v1/quality", qualityRoute);
app.route("/v1", suggestRoute);
// Single source of truth for facts that appear on multiple surfaces.
Expand Down
Loading
Loading