Theme 2: cross-division delivery pipeline (change requests)
A customer change request now flows through a guarded commercial pipeline: Requested -> Estimated -> Approved -> Paid -> Live. The cross-division work and its dependencies live on the request's steps (a division's slice + hours + an optional depends-on link), and estimating sums the steps into a total. Each transition is guarded on the ChangeRequest aggregate, so it can only move forward in order; guard violations surface as 400s. - Domain: ChangeRequest + ChangeRequestStep aggregates with stage guards - Persistence: two tables + EF migration (applied) - Endpoints under /api/orgboard/change-requests: create/list/detail, add/advance steps, and estimate/approve/pay/go-live/reject (reads need board-view, commercial actions are owner-level) - New Delivery pipeline page: request list with stage + step progress, a detail drawer with a stage stepper, the next commercial action, quote entry, and a per-division step breakdown with dependencies Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+110
@@ -170,6 +170,116 @@ namespace TeamUp.Modules.OrgBoard.Persistence.Migrations
|
||||
b.ToTable("agent_profiles", "orgboard");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TeamUp.Modules.OrgBoard.Domain.ChangeRequest", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal?>("Amount")
|
||||
.HasPrecision(12, 2)
|
||||
.HasColumnType("numeric(12,2)");
|
||||
|
||||
b.Property<DateTimeOffset?>("ApprovedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTimeOffset>("CreatedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8)
|
||||
.HasColumnType("character varying(8)");
|
||||
|
||||
b.Property<string>("CustomerName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal?>("EstimateHours")
|
||||
.HasPrecision(9, 2)
|
||||
.HasColumnType("numeric(9,2)");
|
||||
|
||||
b.Property<DateTimeOffset?>("EstimatedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTimeOffset?>("LiveAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("OrganizationId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTimeOffset?>("PaidAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(16)
|
||||
.HasColumnType("character varying(16)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(300)
|
||||
.HasColumnType("character varying(300)");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdatedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrganizationId");
|
||||
|
||||
b.ToTable("change_requests", "orgboard");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TeamUp.Modules.OrgBoard.Domain.ChangeRequestStep", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ChangeRequestId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTimeOffset>("CreatedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid?>("DependsOnStepId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("DivisionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("EstimateHours")
|
||||
.HasPrecision(9, 2)
|
||||
.HasColumnType("numeric(9,2)");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(16)
|
||||
.HasColumnType("character varying(16)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(300)
|
||||
.HasColumnType("character varying(300)");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdatedAtUtc")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChangeRequestId");
|
||||
|
||||
b.ToTable("change_request_steps", "orgboard");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("TeamUp.Modules.OrgBoard.Domain.Division", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
||||
Reference in New Issue
Block a user