data and layout cleanup
This commit is contained in:
@@ -58,6 +58,7 @@ This file is the running release and change log for MRP Codex. Keep it updated w
|
||||
|
||||
### Changed
|
||||
|
||||
- Fresh bootstrap now creates only minimal system records; operational domains no longer start with seeded demo customers, vendors, inventory, BOMs, or warehouses
|
||||
- Sales and purchasing detail pages now expose revision comparison directly alongside chronological revision history
|
||||
- `ROADMAP.md` now tracks remaining work only, and shipped phase history now lives in `SHIPPED.md`
|
||||
- Support logs now prune retained entries by age instead of only trimming by count, and admin diagnostics now reviews filtered support-log summaries instead of an unbounded flat dump
|
||||
|
||||
@@ -230,8 +230,7 @@ The current inventory foundation supports:
|
||||
- item on-hand quantity, stock-by-location balances, and recent stock history
|
||||
- reserved and available quantity visibility by location
|
||||
- item-level file attachments for drawings and support documents
|
||||
- seeded sample inventory items and a starter assembly BOM during bootstrap
|
||||
- seeded sample warehouse and stock locations during bootstrap
|
||||
- fresh bootstrap starts inventory and warehouse data empty so first-run environments do not include demo operational records
|
||||
|
||||
QOL direction:
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ export function GanttPage() {
|
||||
const links = timeline?.links ?? [];
|
||||
const summary = timeline?.summary;
|
||||
const exceptions = timeline?.exceptions ?? [];
|
||||
const ganttCellHeight = 44;
|
||||
const ganttScaleHeight = 56;
|
||||
const ganttHeight = Math.max(420, tasks.length * ganttCellHeight + ganttScaleHeight);
|
||||
|
||||
return (
|
||||
<section className="space-y-4">
|
||||
@@ -104,7 +107,7 @@ export function GanttPage() {
|
||||
</section>
|
||||
<div className="grid gap-3 xl:grid-cols-[minmax(0,1.2fr)_360px]">
|
||||
<div
|
||||
className={`gantt-theme overflow-auto rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5 ${
|
||||
className={`gantt-theme overflow-x-auto overflow-y-visible rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5 ${
|
||||
mode === "dark" ? "wx-willow-dark-theme" : "wx-willow-theme"
|
||||
}`}
|
||||
>
|
||||
@@ -119,15 +122,19 @@ export function GanttPage() {
|
||||
{tasks.length} schedule rows
|
||||
</div>
|
||||
</div>
|
||||
<Gantt
|
||||
tasks={tasks.map((task: GanttTaskDto) => ({
|
||||
...task,
|
||||
start: new Date(task.start),
|
||||
end: new Date(task.end),
|
||||
parent: task.parentId ?? undefined,
|
||||
}))}
|
||||
links={links}
|
||||
/>
|
||||
<div style={{ height: `${ganttHeight}px`, minWidth: "100%" }}>
|
||||
<Gantt
|
||||
tasks={tasks.map((task: GanttTaskDto) => ({
|
||||
...task,
|
||||
start: new Date(task.start),
|
||||
end: new Date(task.end),
|
||||
parent: task.parentId ?? undefined,
|
||||
}))}
|
||||
links={links}
|
||||
cellHeight={ganttCellHeight}
|
||||
scaleHeight={ganttScaleHeight}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<aside className="space-y-3">
|
||||
<section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5">
|
||||
|
||||
@@ -122,152 +122,4 @@ export async function bootstrapAppData() {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if ((await prisma.customer.count()) === 0) {
|
||||
await prisma.customer.createMany({
|
||||
data: [
|
||||
{
|
||||
name: "Acme Components",
|
||||
email: "buyer@acme.example",
|
||||
phone: "555-0101",
|
||||
addressLine1: "1 Industrial Road",
|
||||
addressLine2: "",
|
||||
city: "Detroit",
|
||||
state: "MI",
|
||||
postalCode: "48201",
|
||||
country: "USA",
|
||||
notes: "Priority account",
|
||||
},
|
||||
{
|
||||
name: "Northwind Fabrication",
|
||||
email: "ops@northwind.example",
|
||||
phone: "555-0120",
|
||||
addressLine1: "42 Assembly Ave",
|
||||
addressLine2: "",
|
||||
city: "Milwaukee",
|
||||
state: "WI",
|
||||
postalCode: "53202",
|
||||
country: "USA",
|
||||
notes: "Requires ASN notice",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if ((await prisma.vendor.count()) === 0) {
|
||||
await prisma.vendor.create({
|
||||
data: {
|
||||
name: "SteelSource Supply",
|
||||
email: "sales@steelsource.example",
|
||||
phone: "555-0142",
|
||||
addressLine1: "77 Mill Street",
|
||||
addressLine2: "",
|
||||
city: "Gary",
|
||||
state: "IN",
|
||||
postalCode: "46402",
|
||||
country: "USA",
|
||||
notes: "Lead time 5 business days",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if ((await prisma.inventoryItem.count()) === 0) {
|
||||
const plate = await prisma.inventoryItem.create({
|
||||
data: {
|
||||
sku: "RM-PLATE-AL-125",
|
||||
name: "Aluminum Plate 1/8in",
|
||||
description: "Raw aluminum plate stock for fabricated assemblies.",
|
||||
type: "PURCHASED",
|
||||
status: "ACTIVE",
|
||||
unitOfMeasure: "EA",
|
||||
isSellable: false,
|
||||
isPurchasable: true,
|
||||
defaultCost: 42.5,
|
||||
defaultPrice: null,
|
||||
notes: "Primary sheet stock for enclosure fabrication.",
|
||||
},
|
||||
});
|
||||
|
||||
const fastener = await prisma.inventoryItem.create({
|
||||
data: {
|
||||
sku: "HW-SCREW-832",
|
||||
name: "8-32 Socket Head Screw",
|
||||
description: "Standard socket head cap screw for enclosure assemblies.",
|
||||
type: "PURCHASED",
|
||||
status: "ACTIVE",
|
||||
unitOfMeasure: "EA",
|
||||
isSellable: false,
|
||||
isPurchasable: true,
|
||||
defaultCost: 0.18,
|
||||
defaultPrice: null,
|
||||
notes: "Bulk hardware item.",
|
||||
},
|
||||
});
|
||||
|
||||
const assembly = await prisma.inventoryItem.create({
|
||||
data: {
|
||||
sku: "FG-CTRL-BASE",
|
||||
name: "Control Base Assembly",
|
||||
description: "Base enclosure assembly for standard control packages.",
|
||||
type: "ASSEMBLY",
|
||||
status: "ACTIVE",
|
||||
unitOfMeasure: "EA",
|
||||
isSellable: true,
|
||||
isPurchasable: false,
|
||||
defaultCost: 118,
|
||||
defaultPrice: 249,
|
||||
notes: "Starter BOM for the inventory foundation slice.",
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.inventoryBomLine.createMany({
|
||||
data: [
|
||||
{
|
||||
parentItemId: assembly.id,
|
||||
componentItemId: plate.id,
|
||||
quantity: 2,
|
||||
unitOfMeasure: "EA",
|
||||
notes: "Side panel blanks",
|
||||
position: 10,
|
||||
},
|
||||
{
|
||||
parentItemId: assembly.id,
|
||||
componentItemId: fastener.id,
|
||||
quantity: 12,
|
||||
unitOfMeasure: "EA",
|
||||
notes: "General assembly hardware",
|
||||
position: 20,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if ((await prisma.warehouse.count()) === 0) {
|
||||
await prisma.warehouse.create({
|
||||
data: {
|
||||
code: "MAIN",
|
||||
name: "Main Warehouse",
|
||||
notes: "Primary stocking location for finished goods and purchased materials.",
|
||||
locations: {
|
||||
create: [
|
||||
{
|
||||
code: "RECV",
|
||||
name: "Receiving",
|
||||
notes: "Initial inbound inspection and receipt staging.",
|
||||
},
|
||||
{
|
||||
code: "STOCK-A1",
|
||||
name: "Aisle A1",
|
||||
notes: "General rack storage for standard material.",
|
||||
},
|
||||
{
|
||||
code: "FG-STAGE",
|
||||
name: "Finished Goods Staging",
|
||||
notes: "Outbound-ready finished assemblies.",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user