1
0
Fork 0
mirror of https://github.com/maziggy/bambuddy.git synced 2026-05-09 08:25:54 +02:00

[GH-ISSUE #342] [Feature]: Multi-Run Order / Batch Scheduling for Multi-Plate Files #218

Open
opened 2026-05-07 00:07:46 +02:00 by BreizhHardware · 15 comments

Originally created by @cimdDev on GitHub (Feb 12, 2026).
Original GitHub issue: https://github.com/maziggy/bambuddy/issues/342

Originally assigned to: @maziggy on GitHub.

Problem or Use Case

Currently, when a sliced .gcode.3mf file contains multiple plates and different quantities are required per plate, each individual print run must be manually scheduled.

Example:
Plate 1 → 1x
Plate 2 → 2x
Plate 3 → 3x

The user must manually queue 6 separate print jobs and track completion and cost externally.
This becomes cumbersome and error-prone when:

  • A multi-plate file requires different quantities per plate
  • Printers are used in lab/shared environments with multiple users
    • Several runs must be scheduled over time
    • Jobs are executed by multiple users
    • Jobs are distributed across multiple printers

In these scenarios, managing required quantities per plate quickly becomes untidy and difficult to track reliably.

Proposed Solution

Introduce an Order / Batch layer above individual print jobs.

An Order should:

  • Reference one .gcode.3mf file
  • Allow defining quantity per plate
  • Automatically generate the required number of print jobs
  • Track overall progress
  • Aggregate total and running cost

Core Functionality

  1. Create Order from .gcode.3mf File
  • Button on archive card: "Create Order"
  • Dialog to define quantity per plate
  1. Automatic Job Creation
  • System creates individual print jobs
  • All jobs linked to an order_id
  • automatically queue them to be individually assigned to printers, scheduled, and managed using the existing printer queue workflow.
  1. Progress Tracking
  • Order view shows:
    • Total runs
    • Completed
    • Failed
    • Remaining
    • % Progress
  1. Cost Aggregation
  • Running cost (completed jobs)
  • Estimated total cost (remaining jobs)
  • Failure cost included

Alternatives Considered

Use Existing "Project" Feature

The existing Project concept already moves in a similar direction. It allows grouping multiple files, managing a duedate/timeline, and tracking associated bill of materials (e.g., screws, bearings, and other non-print components).

However, the Project feature currently operates at a higher organizational level and does not provide:

  • Plate-level quantity definition
  • Automatic generation of multiple print runs per plate
  • Queue management for required quantities
  • Progress tracking per plate
  • Aggregated cost tracking based on actual completed runs

Projects are well suited for grouping files and maintaining a high-level overview of print counts. That works great for single plate jobs, but they do not solve the operational problem of:

  • Scheduling multiple required runs of individual plates
  • Tracking how many required plate runs have been completed
  • Monitoring real-time progress and total cost for a batch of identical runs

Therefore, while Projects provide structural grouping and planning capabilities, they do not cover the production-level execution and accounting requirements for multi plates jobs described in this proposal.

This proposal complements the Project feature by introducing execution-level tracking rather than replacing it.

Feature Category

Print Queue & Scheduling

Priority

Would improve my workflow

Mockups or Examples

No response

Contribution

  • I would be willing to help implement this feature

Checklist

  • I have searched existing issues to ensure this feature hasn't already been requested
Originally created by @cimdDev on GitHub (Feb 12, 2026). Original GitHub issue: https://github.com/maziggy/bambuddy/issues/342 Originally assigned to: @maziggy on GitHub. ### Problem or Use Case Currently, when a sliced .gcode.3mf file contains multiple plates and different quantities are required per plate, each individual print run must be manually scheduled. Example: Plate 1 → 1x Plate 2 → 2x Plate 3 → 3x The user must manually queue 6 separate print jobs and track completion and cost externally. This becomes cumbersome and error-prone when: - A multi-plate file requires different quantities per plate - Printers are used in lab/shared environments with multiple users - Several runs must be scheduled over time - Jobs are executed by multiple users - Jobs are distributed across multiple printers In these scenarios, managing required quantities per plate quickly becomes untidy and difficult to track reliably. ### Proposed Solution ### Introduce an Order / Batch layer above individual print jobs. **An Order should:** - Reference one .gcode.3mf file - Allow defining quantity per plate - Automatically generate the required number of print jobs - Track overall progress - Aggregate total and running cost **Core Functionality** 1. Create Order from .gcode.3mf File - Button on archive card: "Create Order" - Dialog to define quantity per plate 2. Automatic Job Creation - System creates individual print jobs - All jobs linked to an order_id - automatically queue them to be individually assigned to printers, scheduled, and managed using the existing printer queue workflow. 3. Progress Tracking - Order view shows: - Total runs - Completed - Failed - Remaining - % Progress 4. Cost Aggregation - Running cost (completed jobs) - Estimated total cost (remaining jobs) - Failure cost included ### Alternatives Considered ### Use Existing "Project" Feature The existing Project concept already moves in a similar direction. It allows grouping multiple files, managing a duedate/timeline, and tracking associated bill of materials (e.g., screws, bearings, and other non-print components). However, the Project feature currently operates at a higher organizational level and does not provide: - Plate-level quantity definition - Automatic generation of multiple print runs per plate - Queue management for required quantities - Progress tracking per plate - Aggregated cost tracking based on actual completed runs Projects are well suited for grouping files and maintaining a high-level overview of print counts. That works great for single plate jobs, but they do not solve the operational problem of: - Scheduling multiple required runs of individual plates - Tracking how many required plate runs have been completed - Monitoring real-time progress and total cost for a batch of identical runs Therefore, while Projects provide structural grouping and planning capabilities, they do not cover the production-level execution and accounting requirements for multi plates jobs described in this proposal. This proposal complements the Project feature by introducing execution-level tracking rather than replacing it. ### Feature Category Print Queue & Scheduling ### Priority Would improve my workflow ### Mockups or Examples _No response_ ### Contribution - [ ] I would be willing to help implement this feature ### Checklist - [x] I have searched existing issues to ensure this feature hasn't already been requested
Author
Owner

@maziggy commented on GitHub (Feb 12, 2026):

Very good idea. Will definitely look into this, but I first have to finish some other tasks. I'll keep you updated.

<!-- gh-comment-id:3890242117 --> @maziggy commented on GitHub (Feb 12, 2026): Very good idea. Will definitely look into this, but I first have to finish some other tasks. I'll keep you updated.
Author
Owner

@cimdDev commented on GitHub (Feb 12, 2026):

I don’t feel I currently have the skills or enough understanding of the codebase to implement this feature myself, but I’m happy to contribute on the conceptual side. Let me know how I can support.

<!-- gh-comment-id:3890542166 --> @cimdDev commented on GitHub (Feb 12, 2026): I don’t feel I currently have the skills or enough understanding of the codebase to implement this feature myself, but I’m happy to contribute on the conceptual side. Let me know how I can support.
Author
Owner

@cimdDev commented on GitHub (Feb 12, 2026):

I am currently studying the codebase, especially the data model and database schema.
But first I’d like to validate my understanding of the current structure.

My current Understanding of Bambuddy’s Data Model is:
LibraryFile → stored file in the library (.3mf / .gcode / others)
PrintArchive → archived print record (created during/after a run)
PrintQueueItem → queued job pointing to either archive_id or library_file_id (+ optional plate_id)
Project → grouping layer to organize related prints (archives + queue items) plus planning features like due date, priority, notes, attachments, tags, BOM items, etc. (Project.archives, Project.queue_items, ProjectBOMItem, …)

For implementing proper multi-plate quantity tracking and production workflows, two structural pieces are missing:

An Order / Batch layer:

  • Define quantity per plate
  • Track progress across multiple runs
  • Aggregate total / running / failure cost

A canonical file identity:

  • A single representation of a slicer artifact
  • Referenced consistently by both Library and Archive

Conceptually, I think the domain could be split into 4 layers:

  1. Asset (the “what”)
    Canonical .3mf/.gcode with extracted metadata (plates, materials, settings, etc.)

  2. Plan (the “intent”)
    An Order that defines required quantity per plate.

  3. Dispatch (the “work items”)
    Individual units that get queued and scheduled (reusing the existing queue logic).

  4. Run (the “facts”)
    What actually happened on the printer (essentially today’s PrintArchive).

This separation would make things clearer:

  • Order progress = derived from dispatch + runs
  • Archive card = a run linked to an asset
  • Library card = an asset (plus storage location)
  • Projects remain high-level grouping
  • Orders handle production-level execution

Does this direction make sense within Bambuddy’s architecture, or would you approach this differently?
This sounds like a fairly invasive change to the current structure and data model of Bambuddy. You have a clearer view of the overall design and propably might see a more direct or simpler way to achieve this.

Anyways, thanks for this awesome project.. And I’m happy to help wherever I can.

<!-- gh-comment-id:3891559658 --> @cimdDev commented on GitHub (Feb 12, 2026): I am currently studying the codebase, especially the data model and database schema. But first I’d like to validate my understanding of the current structure. My current Understanding of Bambuddy’s Data Model is: LibraryFile → stored file in the library (.3mf / .gcode / others) PrintArchive → archived print record (created during/after a run) PrintQueueItem → queued job pointing to either archive_id or library_file_id (+ optional plate_id) Project → grouping layer to organize related prints (archives + queue items) plus planning features like due date, priority, notes, attachments, tags, BOM items, etc. (Project.archives, Project.queue_items, ProjectBOMItem, …) For implementing proper multi-plate quantity tracking and production workflows, two structural pieces are missing: An Order / Batch layer: - Define quantity per plate - Track progress across multiple runs - Aggregate total / running / failure cost A canonical file identity: - A single representation of a slicer artifact - Referenced consistently by both Library and Archive Conceptually, I think the domain could be split into 4 layers: 1. Asset (the “what”) Canonical .3mf/.gcode with extracted metadata (plates, materials, settings, etc.) 2. Plan (the “intent”) An Order that defines required quantity per plate. 3. Dispatch (the “work items”) Individual units that get queued and scheduled (reusing the existing queue logic). 4. Run (the “facts”) What actually happened on the printer (essentially today’s PrintArchive). This separation would make things clearer: - Order progress = derived from dispatch + runs - Archive card = a run linked to an asset - Library card = an asset (plus storage location) - Projects remain high-level grouping - Orders handle production-level execution Does this direction make sense within Bambuddy’s architecture, or would you approach this differently? This sounds like a fairly invasive change to the current structure and data model of Bambuddy. You have a clearer view of the overall design and propably might see a more direct or simpler way to achieve this. Anyways, thanks for this awesome project.. And I’m happy to help wherever I can.
Author
Owner

@maziggy commented on GitHub (Feb 19, 2026):

Took the time to think about it.

Your analysis of the current data model is spot on. I think the 4-layer conceptual breakdown (Asset/Plan/Dispatch/Run) is a useful way to think about it, but the good news is the existing model already covers 3 of those 4 layers — LibraryFile (Asset), PrintQueueItem (Dispatch), and PrintArchive (Run). So we really only need to add the missing "Plan/Order" layer without restructuring everything else.

The approach I'm thinking about is:

  1. New PrintBatch model — references a library file, optional project link, name, status
  2. New PrintBatchPlate model — plate ID + quantity per batch
  3. Add a batch_id FK to PrintQueueItem — links auto-generated queue items back to their batch

When you create a batch, the system generates the right number of PrintQueueItem rows per plate — then the existing scheduler, queue page, and printer workflow handle everything from there. Progress and cost are derived from the queue item/archive statuses, no duplication needed.

This keeps the change additive and let batches optionally sit inside Projects for higher-level organization.

<!-- gh-comment-id:3927331378 --> @maziggy commented on GitHub (Feb 19, 2026): Took the time to think about it. Your analysis of the current data model is spot on. I think the 4-layer conceptual breakdown (Asset/Plan/Dispatch/Run) is a useful way to think about it, but the good news is the existing model already covers 3 of those 4 layers — LibraryFile (Asset), PrintQueueItem (Dispatch), and PrintArchive (Run). So we really only need to add the missing "Plan/Order" layer without restructuring everything else. The approach I'm thinking about is: 1. New PrintBatch model — references a library file, optional project link, name, status 2. New PrintBatchPlate model — plate ID + quantity per batch 3. Add a batch_id FK to PrintQueueItem — links auto-generated queue items back to their batch When you create a batch, the system generates the right number of PrintQueueItem rows per plate — then the existing scheduler, queue page, and printer workflow handle everything from there. Progress and cost are derived from the queue item/archive statuses, no duplication needed. This keeps the change additive and let batches optionally sit inside Projects for higher-level organization.
Author
Owner

@cimdDev commented on GitHub (Feb 20, 2026):

I’ve been thinking a bit more about how a batch/order workflow could look from a user perspective. These are just ideas and absolutely subject to change if better approaches emerge or you already have a clear vision for this.

One concept that might fit well is having a dedicated Batch / Order page where all orders are managed. An order would reference a single library file and show an overview of the plate configuration extracted from the 3MF. The order itself could contain header-level metadata such as name, due date, notes, optional project link, customer, etc.

Inside the order, each plate could then be composed into one or more configurations. Since the material slots and nozzle assignment are already defined in the library file metadata, the order would mainly define:

  • Quantity
  • Material / color mapping per slot

Example:

  • Plate 1 → 5× (mat1: red, mat2: blue)
  • Plate 1 → 2× (mat1: black, mat2: blue)
  • Plate 1 → 3× (mat1: red, mat2: white)
  • Plate 2 → 4× (mat1: black)
  • Plate 4 → 10× (mat1: black, mat2: white, mat3: red)
  • Plate 3 → not required (qty 0)

Each configuration could then have its own progress tracking (printed / failed / remaining), with running cost and estimated cost both per plate and aggregated for the whole order.

It could also be useful if orders remain editable while running, since production requirements often change mid-process.

For dispatching, I could imagine two possible modes:

  • Full auto generation — once defined, all required queue items are created immediately. If the order changes, queued items get adjusted.
  • Manual / staged dispatch — queue items are generated from the order page on demand (partially or fully).

Printer assignment could either target a specific printer or a compatible printer type (e.g., “any H2D Pro”), based on the file compatibility.

Again, these are just workflow thoughts from a user perspective. The direction you described already sounds very aligned with this kind of model.

please let me know where I could contribute or what would help you the most. I’m happy to support on the conceptual side, UX/workflow thinking, data model, testing, or documenting use cases and edge cases. I’d be glad to help. Just point me in the right direction

Really excited to see where this goes

<!-- gh-comment-id:3932886006 --> @cimdDev commented on GitHub (Feb 20, 2026): I’ve been thinking a bit more about how a batch/order workflow could look from a user perspective. These are just ideas and absolutely subject to change if better approaches emerge or you already have a clear vision for this. One concept that might fit well is having a dedicated Batch / Order page where all orders are managed. An order would reference a single library file and show an overview of the plate configuration extracted from the 3MF. The order itself could contain header-level metadata such as name, due date, notes, optional project link, customer, etc. Inside the order, each plate could then be composed into one or more configurations. Since the material slots and nozzle assignment are already defined in the library file metadata, the order would mainly define: - Quantity - Material / color mapping per slot Example: - Plate 1 → 5× (mat1: red, mat2: blue) - Plate 1 → 2× (mat1: black, mat2: blue) - Plate 1 → 3× (mat1: red, mat2: white) - Plate 2 → 4× (mat1: black) - Plate 4 → 10× (mat1: black, mat2: white, mat3: red) - Plate 3 → not required (qty 0) Each configuration could then have its own progress tracking (printed / failed / remaining), with running cost and estimated cost both per plate and aggregated for the whole order. It could also be useful if orders remain editable while running, since production requirements often change mid-process. For dispatching, I could imagine two possible modes: - Full auto generation — once defined, all required queue items are created immediately. If the order changes, queued items get adjusted. - Manual / staged dispatch — queue items are generated from the order page on demand (partially or fully). Printer assignment could either target a specific printer or a compatible printer type (e.g., “any H2D Pro”), based on the file compatibility. Again, these are just workflow thoughts from a user perspective. The direction you described already sounds very aligned with this kind of model. please let me know where I could contribute or what would help you the most. I’m happy to support on the conceptual side, UX/workflow thinking, data model, testing, or documenting use cases and edge cases. I’d be glad to help. Just point me in the right direction Really excited to see where this goes
Author
Owner

@maziggy commented on GitHub (Feb 20, 2026):

Perhaps @cadtoolbox has also an opinion on this?

<!-- gh-comment-id:3932909732 --> @maziggy commented on GitHub (Feb 20, 2026): Perhaps @cadtoolbox has also an opinion on this?
Author
Owner

@maziggy commented on GitHub (Feb 20, 2026):

I would says let's first define the exact workflow. I just started with a larger task, but once it's finished, I can step in here.

<!-- gh-comment-id:3932943560 --> @maziggy commented on GitHub (Feb 20, 2026): I would says let's first define the exact workflow. I just started with a larger task, but once it's finished, I can step in here.
Author
Owner

@cadtoolbox commented on GitHub (Feb 20, 2026):

@maziggy The majority of the print jobs we use are single build plate. Lot's a prints, but almost never repeats. I would not have a vested interest in this to offer a decent opinion.

<!-- gh-comment-id:3933426731 --> @cadtoolbox commented on GitHub (Feb 20, 2026): @maziggy The majority of the print jobs we use are single build plate. Lot's a prints, but almost never repeats. I would not have a vested interest in this to offer a decent opinion.
Author
Owner

@cimdDev commented on GitHub (Feb 20, 2026):

I will spend some more time thinking about this... This idea needs a bit more maturing. It’s something that should be done right rather than fast...

I’m also considering related requirements raised by jnswlln on Discord. Their use case is a larger farm where orders are defined as product + color + quantity, and the system automatically maps jobs to any available printer that already has the required filament/color configured. That kind of self-mapping to existing printer material/color setups is an interesting direction and could also well align within this concept here.

I also think accounting per plate vs per object on a plate needs some thoughts, although it does add complexity.

Just sharing thoughts for now. I will refine ideas further

<!-- gh-comment-id:3933740354 --> @cimdDev commented on GitHub (Feb 20, 2026): I will spend some more time thinking about this... This idea needs a bit more maturing. It’s something that should be done right rather than fast... I’m also considering related requirements raised by jnswlln on Discord. Their use case is a larger farm where orders are defined as product + color + quantity, and the system automatically maps jobs to any available printer that already has the required filament/color configured. That kind of self-mapping to existing printer material/color setups is an interesting direction and could also well align within this concept here. I also think accounting per plate vs per object on a plate needs some thoughts, although it does add complexity. Just sharing thoughts for now. I will refine ideas further
Author
Owner

@cimdDev commented on GitHub (Feb 23, 2026):

I worked on it conceptually the last couple of days to explore the approach and validate the direction. I created a small prototype MVP with Codex for demonstration purposes.. nothing that’s worthy of a pull request, but I hope this helps to convey the idea or partailly reuse for the implementation.

Here’s the complete documentation and summary of this feature:

Batch Order From 3MF + Plate Configuration Matrix (Technical Documentation)

1. Feature Overview

What the Batch Order feature does

The Batch Order feature adds a planning layer above the existing queue so users can define what must be produced from a .gcode.3mf file before dispatching individual prints.

It allows users to:

  • Create an Order from a Library 3MF file
  • See all plates extracted from the 3MF metadata
  • Define multiple per-plate configurations (variants)
  • Set target quantities per configuration
  • Override colors per material/slot while keeping the original plate geometry/toolpath
  • Dispatch remaining work into the existing queue (full or partial)

Purpose of creating orders from 3MF files

A Library .gcode.3mf file already contains:

  • plate definitions
  • per-plate filament/material usage
  • estimated time/weight
  • color/material metadata

Creating an Order from the 3MF uses that metadata as the source of truth for plate planning.

Plate Configurations

A Plate Configuration represents:

“Print this specific source plate with this color setup, this many times.”

Each configuration is tied to one source plate and contains:

  • quantity_target
  • optional name/label
  • per-slot material/color values (seeded from the original 3MF plate mapping)

Color Overrides

Overrides are primarily color changes (material type remains unchanged).

Example:

  • Base: PLA #FF0000
  • Override: PLA #0000FF

The UI and backend preserve the source mapping and compute a queue-level override payload describing only the differences.

Integration with the existing Queue system

The queue architecture is reused as-is.

  • No new queue system was introduced.
  • Batch dispatch creates normal PrintQueueItem rows.
  • Queue matching / AMS slot resolution remains in the existing queue/scheduler logic.
  • Queue items now optionally carry override_material_map to represent batch configuration overrides.

2. Workflow Description

1. Create a Batch Order from a .gcode.3mf file

User flow:

  • From File Manager, user selects Create Batch Order on a .gcode.3mf file.
  • System calls POST /orders.

Internal behavior:

  • Backend validates the source is a .gcode.3mf library file.
  • Source metadata is loaded from LibraryFile.file_metadata.
  • If normalized plates[] is missing, backend extracts plate snapshots directly from the 3MF archive.
  • A PrintBatch row is created and per-plate PrintBatchPlate rows are snapshotted.

2. Edit header information

User can edit:

  • order name
  • customer label
  • due date
  • notes
  • ...

Internal behavior:

  • PUT /orders/{id} updates print_batches
  • planning metadata changes do not mutate historical queue/archive rows

3. Define plate configurations

User creates one or more configurations per plate.

Internal behavior:

  • POST /orders/{id}/configs
  • Config rows are created in print_batch_plate_configs
  • Slot mappings are seeded from the plate’s plate_metadata_snapshot.filament_map
  • Seeded slots are stored in print_batch_plate_config_slots

4. Override colors

User edits colors in the matrix per slot row / config column.

Internal behavior:

  • UI updates config draft state
  • Save action performs:
    • config update (PUT /orders/configs/{config_id})
    • slot replacement (PUT /orders/configs/{config_id}/slots)
  • Backend recalculates queue-facing snapshots for pending items linked to that config

5. Generate QueueItems

When user dispatches a config / plate / order:

  • Backend computes remaining_to_dispatch
  • Creates one PrintQueueItem per physical print
  • Each queue item includes batch linkage + configuration snapshots

Queue item payload includes:

  • batch_id, batch_plate_id, batch_plate_config_id
  • matching_requirements_json
  • execution_mapping_json
  • override_material_map (if effective overrides exist)

6. Dispatch prints

Dispatch entry points:

  • Order-level dispatch
  • Plate-level dispatch
  • Config-level dispatch
  • Optional partial limit

Internal behavior:

  • Batch service inserts queue items only to "Any of type x printer"
  • Existing scheduler/queue picks them up normally
  • On execution archive creation, batch lineage and overrides are snapshotted into archive.extra_data["batch_order"]

3. Data Model and Architecture Changes

New planning tables

  • print_batches (order header)
  • print_batch_plates (source plate snapshot)
  • print_batch_plate_configs (plate variants + quantity)
  • print_batch_plate_config_slots (per-slot material/color mapping for a config)

Schema change (new for this feature refinement)

print_queue gained:

  • override_material_map (TEXT, JSON-serialized, nullable)

Purpose:

  • Stores per-queue-item configuration overrides derived from a plate config
  • Keeps queue matching architecture unchanged while making override intent explicit

Relationships

  • PrintBatch 1..N PrintBatchPlate
  • PrintBatchPlate 1..N PrintBatchPlateConfig
  • PrintBatchPlateConfig 1..N PrintBatchPlateConfigSlot
  • PrintBatchPlateConfig 1..N PrintQueueItem (via batch_plate_config_id)

Override data flow

3MF (plate filament map)
  -> PrintBatchPlate.plate_metadata_snapshot
  -> seeded PrintBatchPlateConfigSlot rows
  -> user edits color overrides in matrix
  -> PrintBatchService computes effective override delta
  -> PrintQueueItem.override_material_map (dispatch time / pending sync)
  -> existing queue + scheduler consume same queue item model

4. Override Logic

Base material mapping from 3MF

Base mapping is read from:

  • plate.plate_metadata_snapshot.filament_map

Each row typically includes:

  • slot_id
  • material_type
  • color_hex
  • optional nozzle_assignment

Configuration overrides

Each config stores slot mappings in print_batch_plate_config_slots.

The matrix UI edits those rows, usually changing:

  • color_hex

Material type can still be stored, but UI/feature expectation is “color-first”.

Effective mapping determination

At dispatch/sync time, backend compares:

  • base slot mapping (from plate snapshot)
  • config slot mapping (from config slots)

If values differ, an entry is added to override_material_map.

No difference => no override entry for that slot.

Example override payload

{
  "1": {
    "slot_index": 1,
    "filament_id": null,
    "material_type": "PLA",
    "color_hex": "#0000FF",
    "color_family": "blue",
    "nozzle_assignment": "0",
    "base_material_type": "PLA",
    "base_color_hex": "#FF0000",
    "base_color_family": "red",
    "source": "order_plate_config",
    "batch_plate_config_id": 12
  }
}

Queue matching / AMS mapping is not modified

This feature does not change:

  • scheduler matching logic
  • AMS tray selection logic
  • printer assignment logic

It only passes override intent forward via queue item metadata.


5. UI Structure

Order creation screen

Two entry paths exist:

  • File Manager action: Create Batch Order for 3MF files (preferred flow)
  • Orders page (manual create by Library File ID flow)

Order detail layout

Order detail page now contains:

  • Header section (order metadata editor)
  • Progress summary card
  • Plate cards (one per source plate)

Plate card layout

Left side:

  • plate preview image
  • plate metadata / object list / gcode ref
  • plate progress summary
  • plate dispatch control
  • add config control

Right side:

  • configuration matrix (horizontal scroll)

Configuration matrix behavior

Rows:

  • base material/color rows from source plate (filament_map)

Columns:

  • Original (read-only source mapping)
  • one column per active config (editable)

Per config column:

  • config name
  • quantity
  • per-row color override inputs:
    • based on Color Catalog
    • filtered by material
    • optionally filtered by "available in inventory"
  • dispatch action
  • save action
  • remove (implemented as cancel/hide)

Dispatch controls

Available dispatch levels:

  • Order: dispatch remaining (optional limit)
  • Plate: dispatch remaining (optional limit)
  • Config: dispatch remaining (optional limit)

Progress indicators

Displayed at:

  • Order level: aggregated summary
  • Plate level: totals + progress bar + queue/printing/completed/remaining
  • Config level: compact counts in matrix header

Diagram (UI composition)

Order Detail
├─ Header Card (name/customer/due date/notes)
├─ Progress Summary Card
└─ Plate Card (repeated)
   ├─ Left Panel
   │  ├─ Preview
   │  ├─ Plate stats + progress bar
   │  ├─ Dispatch plate
   │  └─ Add config
   └─ Right Panel
      └─ Config Matrix
         ├─ Row labels = base slot/materials
         ├─ Original column (read-only)
         └─ Config columns (editable overrides + qty + dispatch/save)

6. Queue Integration Verification

How QueueItems now receive overrides

During batch dispatch (and pending item sync after config edits):

  • backend compares base plate slots vs config slots
  • backend builds a delta payload (override_material_map)
  • payload is saved on PrintQueueItem.override_material_map

Where override is stored

  • Database column: print_queue.override_material_map
  • Type: JSON serialized into TEXT
  • Response/API schema now parses/returns it as a JSON object

Confirmation that existing queue logic was reused

Reused unchanged:

  • queue item lifecycle/status model
  • scheduler assignment flow
  • AMS matching/resolution logic
  • archive creation flow

Extended only:

  • queue item metadata payload (override field)
  • archive lineage snapshot to include overrides

Compatibility considerations

  • override_material_map is nullable; legacy queue items remain valid
  • Existing queue create/update APIs continue to work without the new field
  • Matching logic does not depend on this field yet, so behavior remains backward-compatible

7. Limitations and Future Extensions

Current limitations

  • Primary override expectation is color; material-type changes are not supported
  • No automatic compensation/planning logic
  • Config removal is implemented as cancel/hide for history safety (not hard delete)

Future extensions

  • Inventory-backed color override selection (filament_id)
  • Constraint-aware validation (e.g. forbid PLA→ABS if config policy disallows)
  • Color tolerance policies (exact, family, distance)
  • Bulk config operations across plates
  • Better conflict detection for concurrent editor sessions
  • Richer normalized requirements table (print_batch_config_requirements) fully wired to UI

8. Developer Notes

Key design decisions

  • Keep queue/scheduler architecture unchanged; add metadata only
  • Store override payload on queue items for traceability and future matching integration
  • Compute overrides as a delta from source plate snapshot, not as a full replacement contract
  • Matrix UI is plate-centric to match how multi-plate 3MF production is planned

Tradeoffs

  • override_material_map in queue is flexible and additive, but not strongly typed at DB level
  • Config “remove” as cancel/hide preserves history but may require UI explanation
  • Matrix save currently performs config update + slot replacement (2 API calls) for simplicity

Things to watch out for

  • Pending queue items are resynced on config changes; started/completed items remain historical by design
  • Base rows come from plate_metadata_snapshot.filament_map; malformed source metadata can degrade matrix fidelity
  • Concurrent edits can cause last-write-wins behavior on config/slot saves

Potential refactoring areas

  • Split matrix column editor into reusable subcomponents
  • Add batch API endpoint for atomic config+slots update (single transaction over one request)
  • Introduce normalized requirement rows for future matching UI and reporting
  • Add stronger typing for override_material_map in frontend API types
<!-- gh-comment-id:3944808815 --> @cimdDev commented on GitHub (Feb 23, 2026): I worked on it conceptually the last couple of days to explore the approach and validate the direction. I created a small prototype MVP with Codex for demonstration purposes.. nothing that’s worthy of a pull request, but I hope this helps to convey the idea or partailly reuse for the implementation. Here’s the complete documentation and summary of this feature: # Batch Order From 3MF + Plate Configuration Matrix (Technical Documentation) ## 1. Feature Overview ### What the Batch Order feature does The Batch Order feature adds a planning layer above the existing queue so users can define **what must be produced** from a `.gcode.3mf` file before dispatching individual prints. It allows users to: - Create an Order from a Library 3MF file - See all plates extracted from the 3MF metadata - Define multiple per-plate configurations (variants) - Set target quantities per configuration - Override colors per material/slot while keeping the original plate geometry/toolpath - Dispatch remaining work into the existing queue (full or partial) ### Purpose of creating orders from 3MF files A Library `.gcode.3mf` file already contains: - plate definitions - per-plate filament/material usage - estimated time/weight - color/material metadata Creating an Order from the 3MF uses that metadata as the **source of truth** for plate planning. ### Plate Configurations A Plate Configuration represents: > “Print this specific source plate with this color setup, this many times.” Each configuration is tied to one source plate and contains: - `quantity_target` - optional name/label - per-slot material/color values (seeded from the original 3MF plate mapping) ### Color Overrides Overrides are primarily **color changes** (material type remains unchanged). Example: - Base: `PLA #FF0000` - Override: `PLA #0000FF` The UI and backend preserve the source mapping and compute a queue-level override payload describing only the differences. ### Integration with the existing Queue system The queue architecture is reused as-is. - No new queue system was introduced. - Batch dispatch creates normal `PrintQueueItem` rows. - Queue matching / AMS slot resolution remains in the existing queue/scheduler logic. - Queue items now optionally carry `override_material_map` to represent batch configuration overrides. --- ## 2. Workflow Description ### 1. Create a Batch Order from a .gcode.3mf file User flow: - From File Manager, user selects **Create Batch Order** on a .gcode.3mf file. - System calls `POST /orders`. Internal behavior: - Backend validates the source is a `.gcode.3mf` library file. - Source metadata is loaded from `LibraryFile.file_metadata`. - If normalized `plates[]` is missing, backend extracts plate snapshots directly from the 3MF archive. - A `PrintBatch` row is created and per-plate `PrintBatchPlate` rows are snapshotted. ### 2. Edit header information User can edit: - order name - customer label - due date - notes - ... Internal behavior: - `PUT /orders/{id}` updates `print_batches` - planning metadata changes do not mutate historical queue/archive rows ### 3. Define plate configurations User creates one or more configurations per plate. Internal behavior: - `POST /orders/{id}/configs` - Config rows are created in `print_batch_plate_configs` - Slot mappings are seeded from the plate’s `plate_metadata_snapshot.filament_map` - Seeded slots are stored in `print_batch_plate_config_slots` ### 4. Override colors User edits colors in the matrix per slot row / config column. Internal behavior: - UI updates config draft state - Save action performs: - config update (`PUT /orders/configs/{config_id}`) - slot replacement (`PUT /orders/configs/{config_id}/slots`) - Backend recalculates queue-facing snapshots for pending items linked to that config ### 5. Generate QueueItems When user dispatches a config / plate / order: - Backend computes `remaining_to_dispatch` - Creates one `PrintQueueItem` per physical print - Each queue item includes batch linkage + configuration snapshots Queue item payload includes: - `batch_id`, `batch_plate_id`, `batch_plate_config_id` - `matching_requirements_json` - `execution_mapping_json` - `override_material_map` (if effective overrides exist) ### 6. Dispatch prints Dispatch entry points: - Order-level dispatch - Plate-level dispatch - Config-level dispatch - Optional partial `limit` Internal behavior: - Batch service inserts queue items only to "Any _of type x_ printer" - Existing scheduler/queue picks them up normally - On execution archive creation, batch lineage and overrides are snapshotted into `archive.extra_data["batch_order"]` --- ## 3. Data Model and Architecture Changes ### New planning tables - `print_batches` (order header) - `print_batch_plates` (source plate snapshot) - `print_batch_plate_configs` (plate variants + quantity) - `print_batch_plate_config_slots` (per-slot material/color mapping for a config) ### Schema change (new for this feature refinement) `print_queue` gained: - `override_material_map` (`TEXT`, JSON-serialized, nullable) Purpose: - Stores per-queue-item configuration overrides derived from a plate config - Keeps queue matching architecture unchanged while making override intent explicit ### Relationships - `PrintBatch` 1..N `PrintBatchPlate` - `PrintBatchPlate` 1..N `PrintBatchPlateConfig` - `PrintBatchPlateConfig` 1..N `PrintBatchPlateConfigSlot` - `PrintBatchPlateConfig` 1..N `PrintQueueItem` (via `batch_plate_config_id`) ### Override data flow ```text 3MF (plate filament map) -> PrintBatchPlate.plate_metadata_snapshot -> seeded PrintBatchPlateConfigSlot rows -> user edits color overrides in matrix -> PrintBatchService computes effective override delta -> PrintQueueItem.override_material_map (dispatch time / pending sync) -> existing queue + scheduler consume same queue item model ``` --- ## 4. Override Logic ### Base material mapping from 3MF Base mapping is read from: - `plate.plate_metadata_snapshot.filament_map` Each row typically includes: - `slot_id` - `material_type` - `color_hex` - optional `nozzle_assignment` ### Configuration overrides Each config stores slot mappings in `print_batch_plate_config_slots`. The matrix UI edits those rows, usually changing: - `color_hex` Material type can still be stored, but UI/feature expectation is “color-first”. ### Effective mapping determination At dispatch/sync time, backend compares: - base slot mapping (from plate snapshot) - config slot mapping (from config slots) If values differ, an entry is added to `override_material_map`. No difference => no override entry for that slot. ### Example override payload ```json { "1": { "slot_index": 1, "filament_id": null, "material_type": "PLA", "color_hex": "#0000FF", "color_family": "blue", "nozzle_assignment": "0", "base_material_type": "PLA", "base_color_hex": "#FF0000", "base_color_family": "red", "source": "order_plate_config", "batch_plate_config_id": 12 } } ``` ### Queue matching / AMS mapping is not modified This feature does **not** change: - scheduler matching logic - AMS tray selection logic - printer assignment logic It only passes override intent forward via queue item metadata. --- ## 5. UI Structure ### Order creation screen Two entry paths exist: - File Manager action: **Create Batch Order** for 3MF files (preferred flow) - Orders page (manual create by Library File ID flow) ### Order detail layout Order detail page now contains: - Header section (order metadata editor) - Progress summary card - Plate cards (one per source plate) ### Plate card layout Left side: - plate preview image - plate metadata / object list / gcode ref - plate progress summary - plate dispatch control - add config control Right side: - configuration matrix (horizontal scroll) ### Configuration matrix behavior Rows: - base material/color rows from source plate (`filament_map`) Columns: - `Original` (read-only source mapping) - one column per active config (editable) Per config column: - config name - quantity - per-row color override inputs: - based on Color Catalog - filtered by material - optionally filtered by "available in inventory" - dispatch action - save action - remove (implemented as cancel/hide) ### Dispatch controls Available dispatch levels: - Order: dispatch remaining (optional limit) - Plate: dispatch remaining (optional limit) - Config: dispatch remaining (optional limit) ### Progress indicators Displayed at: - Order level: aggregated summary - Plate level: totals + progress bar + queue/printing/completed/remaining - Config level: compact counts in matrix header ### Diagram (UI composition) ```text Order Detail ├─ Header Card (name/customer/due date/notes) ├─ Progress Summary Card └─ Plate Card (repeated) ├─ Left Panel │ ├─ Preview │ ├─ Plate stats + progress bar │ ├─ Dispatch plate │ └─ Add config └─ Right Panel └─ Config Matrix ├─ Row labels = base slot/materials ├─ Original column (read-only) └─ Config columns (editable overrides + qty + dispatch/save) ``` --- ## 6. Queue Integration Verification ### How QueueItems now receive overrides During batch dispatch (and pending item sync after config edits): - backend compares base plate slots vs config slots - backend builds a delta payload (`override_material_map`) - payload is saved on `PrintQueueItem.override_material_map` ### Where override is stored - Database column: `print_queue.override_material_map` - Type: JSON serialized into `TEXT` - Response/API schema now parses/returns it as a JSON object ### Confirmation that existing queue logic was reused Reused unchanged: - queue item lifecycle/status model - scheduler assignment flow - AMS matching/resolution logic - archive creation flow Extended only: - queue item metadata payload (override field) - archive lineage snapshot to include overrides ### Compatibility considerations - `override_material_map` is nullable; legacy queue items remain valid - Existing queue create/update APIs continue to work without the new field - Matching logic does not depend on this field yet, so behavior remains backward-compatible --- ## 7. Limitations and Future Extensions ### Current limitations - Primary override expectation is **color**; material-type changes are not supported - No automatic compensation/planning logic - Config removal is implemented as cancel/hide for history safety (not hard delete) ### Future extensions - Inventory-backed color override selection (`filament_id`) - Constraint-aware validation (e.g. forbid PLA→ABS if config policy disallows) - Color tolerance policies (`exact`, `family`, distance) - Bulk config operations across plates - Better conflict detection for concurrent editor sessions - Richer normalized requirements table (`print_batch_config_requirements`) fully wired to UI --- ## 8. Developer Notes ### Key design decisions - Keep queue/scheduler architecture unchanged; add metadata only - Store override payload on queue items for traceability and future matching integration - Compute overrides as a delta from source plate snapshot, not as a full replacement contract - Matrix UI is plate-centric to match how multi-plate 3MF production is planned ### Tradeoffs - `override_material_map` in queue is flexible and additive, but not strongly typed at DB level - Config “remove” as cancel/hide preserves history but may require UI explanation - Matrix save currently performs config update + slot replacement (2 API calls) for simplicity ### Things to watch out for - Pending queue items are resynced on config changes; started/completed items remain historical by design - Base rows come from `plate_metadata_snapshot.filament_map`; malformed source metadata can degrade matrix fidelity - Concurrent edits can cause last-write-wins behavior on config/slot saves ### Potential refactoring areas - Split matrix column editor into reusable subcomponents - Add batch API endpoint for atomic config+slots update (single transaction over one request) - Introduce normalized requirement rows for future matching UI and reporting - Add stronger typing for `override_material_map` in frontend API types
Author
Owner

@cimdDev commented on GitHub (Feb 23, 2026):

https://github.com/cimdDev/bambuddy/tree/custom/feature-orderbatch-mvp

Image
Image
Image
<!-- gh-comment-id:3944952262 --> @cimdDev commented on GitHub (Feb 23, 2026): https://github.com/cimdDev/bambuddy/tree/custom/feature-orderbatch-mvp <img width="1663" height="1038" alt="Image" src="https://github.com/user-attachments/assets/7b1d4814-2a72-45f2-94ae-fc5198d16b78" /> --- <img width="1631" height="507" alt="Image" src="https://github.com/user-attachments/assets/59545a09-bffe-44be-afd7-b2a7017a4876" /> --- <img width="431" height="877" alt="Image" src="https://github.com/user-attachments/assets/cc05b22e-79fb-4d9d-83fe-f750574ca596" />
Author
Owner

@maziggy commented on GitHub (Mar 28, 2026):

Do you wanna push?

<!-- gh-comment-id:4147874773 --> @maziggy commented on GitHub (Mar 28, 2026): Do you wanna push?
Author
Owner

@cimdDev commented on GitHub (Mar 30, 2026):

This is not production-grade code and mostly AI generated. This was meant as a quick proof of concept demo to explore and convey the idea, rather than deliver a ready to push feature. The backend logic could maybe be serve as a starting point for further development, but frontend definitely needs a redesign. it looks quite clunky and ugly. I am not able to take this further. If you think this direction is valuable and want to turn it into a production-ready feature, I’m happy to push it as-is.

<!-- gh-comment-id:4153138160 --> @cimdDev commented on GitHub (Mar 30, 2026): This is not production-grade code and mostly AI generated. This was meant as a quick proof of concept demo to explore and convey the idea, rather than deliver a ready to push feature. The backend logic could maybe be serve as a starting point for further development, but frontend definitely needs a redesign. it looks quite clunky and ugly. I am not able to take this further. If you think this direction is valuable and want to turn it into a production-ready feature, I’m happy to push it as-is.
Author
Owner

@maziggy commented on GitHub (Apr 1, 2026):

Let's start with a simplified approach. Add quantity option to print/schedule modal. If quantity > 1, it starts the first print and creates required queue items identified by a batchID for tracking.

<!-- gh-comment-id:4168560068 --> @maziggy commented on GitHub (Apr 1, 2026): Let's start with a simplified approach. Add quantity option to print/schedule modal. If quantity > 1, it starts the first print and creates required queue items identified by a batchID for tracking.
Author
Owner

@maziggy commented on GitHub (Apr 1, 2026):

Available/Fixed in branch dev and available with the next release or daily build.

Can you please test and let me know how it goes?


If you find Bambuddy useful, please consider giving it a on GitHub — it helps others discover the project!

<!-- gh-comment-id:4168915548 --> @maziggy commented on GitHub (Apr 1, 2026): Available/Fixed in branch dev and available with the next release or daily build. Can you please test and let me know how it goes? ----- If you find Bambuddy useful, please consider giving it a ⭐ on [GitHub](https://github.com/maziggy/bambuddy) — it helps others discover the project!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy-maziggy-1#218
No description provided.