Add Motion: the go-to-market operating system on top of the ledger
The ledger answers which contracted capacity is sold, to whom, at what margin. It says nothing about the motion — the repeatable practice that turns a customer conversation into a scoped deployment, and turns that deployment into something the next one reuses. Motion is deliberately not a parallel entity tree. DEMAND_STAGES already is the motion, so Motion binds reusable artefacts to the stages of a demand deal that already exists: an engagement hangs off one deal, cascade deleted, one per deal by unique constraint. Nine closed kinds, each declaring which stages it serves, and a starter library of twelve templates covering all eight open stages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* The shape a template arrives in on the wire.
|
||||
*
|
||||
* It describes a *response*, not the server's own row, so it is declared here
|
||||
* rather than imported from `@pig/db`: a column the API does not serialise must
|
||||
* be absent, and one it may not have joined yet must be optional, or the
|
||||
* compiler asserts a guarantee the JSON does not carry. The enums are the
|
||||
* exception — those come from `@pig/core`, because a kind the ontology has
|
||||
* dropped should stop compiling rather than keep rendering.
|
||||
*
|
||||
* `fields` is the deliberate hole in the type. It is author-written JSON whose
|
||||
* shape varies by kind and is not validated on the way out of the database, so
|
||||
* it arrives as `unknown` and is narrowed at the point of use in `FieldsView`.
|
||||
* Typing it as the shape we hope for would move a runtime crash into a place
|
||||
* where nobody is looking for it.
|
||||
*
|
||||
* There is only one type here on purpose. Eight more were written alongside it
|
||||
* and never imported, and by the time anyone read them they no longer matched
|
||||
* `services/motion.ts` — `EngagementDetail` promised `.artifacts` where the
|
||||
* endpoint returns `.stages`. Each page declares the subset of the response it
|
||||
* actually reads, which is checked against the `get<T>()` call that fetches it;
|
||||
* a shared file that nothing imports is checked against nothing at all.
|
||||
*/
|
||||
import type { DemandStage, MotionKind, MotionVisibility } from '@pig/core';
|
||||
|
||||
export interface MotionTemplateView {
|
||||
id: string;
|
||||
kind: MotionKind;
|
||||
/** Stable across versions — the identity of the lineage, not of the row. */
|
||||
slug: string;
|
||||
version: number;
|
||||
title: string;
|
||||
summary: string;
|
||||
body: string;
|
||||
fields: unknown;
|
||||
stage: DemandStage;
|
||||
visibility: MotionVisibility;
|
||||
ownerUserId: string | null;
|
||||
ownerName?: string | null;
|
||||
supersedesId: string | null;
|
||||
originArtifactId: string | null;
|
||||
isSystem: boolean;
|
||||
usageCount: number;
|
||||
archivedAt: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
Reference in New Issue
Block a user