Add job brackets for grouping multi-part or repeated jobs

- JobBracket model: name, customer, notes
- Migration 0006: job_brackets table + bracket_id FK on print_jobs
- /brackets: list with per-bracket progress bar
- /brackets/{id}: detail with jobs table + Add Job(s) modal (quantity field
  creates N identical jobs in one shot, each with its own UUID and log entry)
- /jobs Add Job modal: optional bracket selector
- Sidebar: Brackets nav item added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Hohenberg
2026-06-18 22:03:01 +02:00
parent 977e0deb24
commit ccf6a64787
9 changed files with 398 additions and 1 deletions

View File

@@ -0,0 +1,37 @@
"""job_brackets table and bracket_id on print_jobs
Revision ID: 0006
Revises: 0005
Create Date: 2026-06-18
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "0006"
down_revision: Union[str, None] = "0005"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"job_brackets",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(200), nullable=False),
sa.Column("customer", sa.String(200), nullable=True),
sa.Column("notes", sa.Text(), nullable=True),
sa.Column("created_at", sa.DateTime(), nullable=False, server_default=sa.text("CURRENT_TIMESTAMP")),
sa.Column("updated_at", sa.DateTime(), nullable=False, server_default=sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")),
sa.PrimaryKeyConstraint("id"),
)
op.add_column("print_jobs", sa.Column("bracket_id", sa.Integer(), nullable=True))
op.create_foreign_key("fk_job_bracket", "print_jobs", "job_brackets", ["bracket_id"], ["id"])
def downgrade() -> None:
op.drop_constraint("fk_job_bracket", "print_jobs", type_="foreignkey")
op.drop_column("print_jobs", "bracket_id")
op.drop_table("job_brackets")