Add step type support for work order profiles and steps, update database schema, APIs, and UI components to handle configurable step types.
This commit is contained in:
@@ -178,14 +178,17 @@ func (h *ProfileHandler) CreateStep(w http.ResponseWriter, r *http.Request) {
|
||||
respondError(w, http.StatusBadRequest, "title required")
|
||||
return
|
||||
}
|
||||
if body.StepType == "" {
|
||||
body.StepType = "work_step"
|
||||
}
|
||||
var maxOrder int
|
||||
h.db.QueryRow(`SELECT ISNULL(MAX(step_order),0) FROM wo_profile_steps WHERE profile_id=@p1`, profileID).Scan(&maxOrder)
|
||||
|
||||
var sid int
|
||||
err = h.db.QueryRow(`
|
||||
INSERT INTO wo_profile_steps (profile_id, step_order, title, description, required)
|
||||
OUTPUT INSERTED.id VALUES (@p1, @p2, @p3, @p4, @p5)`,
|
||||
profileID, maxOrder+1, body.Title, body.Description, body.Required,
|
||||
INSERT INTO wo_profile_steps (profile_id, step_order, title, description, required, step_type, type_config)
|
||||
OUTPUT INSERTED.id VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7)`,
|
||||
profileID, maxOrder+1, body.Title, body.Description, body.Required, body.StepType, body.TypeConfig,
|
||||
).Scan(&sid)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, err.Error())
|
||||
@@ -207,8 +210,11 @@ func (h *ProfileHandler) UpdateStep(w http.ResponseWriter, r *http.Request) {
|
||||
respondError(w, http.StatusBadRequest, "title required")
|
||||
return
|
||||
}
|
||||
h.db.Exec(`UPDATE wo_profile_steps SET title=@p1, description=@p2, required=@p3, step_order=@p4 WHERE id=@p5`,
|
||||
body.Title, body.Description, body.Required, body.StepOrder, sid)
|
||||
if body.StepType == "" {
|
||||
body.StepType = "work_step"
|
||||
}
|
||||
h.db.Exec(`UPDATE wo_profile_steps SET title=@p1, description=@p2, required=@p3, step_order=@p4, step_type=@p5, type_config=@p6 WHERE id=@p7`,
|
||||
body.Title, body.Description, body.Required, body.StepOrder, body.StepType, body.TypeConfig, sid)
|
||||
var step model.ProfileStep
|
||||
h.db.Get(&step, `SELECT * FROM wo_profile_steps WHERE id=@p1`, sid)
|
||||
respond(w, http.StatusOK, step)
|
||||
@@ -262,10 +268,13 @@ func (h *ProfileHandler) Apply(w http.ResponseWriter, r *http.Request) {
|
||||
h.db.QueryRow(`SELECT ISNULL(MAX(step_order),0) FROM wo_steps WHERE wo_id=@p1`, woID).Scan(&maxOrder)
|
||||
|
||||
for _, s := range steps {
|
||||
if s.StepType == "" {
|
||||
s.StepType = "work_step"
|
||||
}
|
||||
h.db.Exec(`
|
||||
INSERT INTO wo_steps (wo_id, step_order, title, description, required)
|
||||
VALUES (@p1, @p2, @p3, @p4, @p5)`,
|
||||
woID, maxOrder+s.StepOrder, s.Title, s.Description, s.Required)
|
||||
INSERT INTO wo_steps (wo_id, step_order, title, description, required, step_type, type_config)
|
||||
VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7)`,
|
||||
woID, maxOrder+s.StepOrder, s.Title, s.Description, s.Required, s.StepType, s.TypeConfig)
|
||||
}
|
||||
|
||||
// Fill instructions if blank; update priority only on draft WOs
|
||||
|
||||
@@ -41,11 +41,14 @@ func (h *StepHandler) Create(w http.ResponseWriter, r *http.Request) {
|
||||
var maxOrder int
|
||||
h.db.QueryRow(`SELECT ISNULL(MAX(step_order),0) FROM wo_steps WHERE wo_id=@p1`, woID).Scan(&maxOrder)
|
||||
|
||||
if body.StepType == "" {
|
||||
body.StepType = "work_step"
|
||||
}
|
||||
var sid int
|
||||
err = h.db.QueryRow(`
|
||||
INSERT INTO wo_steps (wo_id,step_order,title,description,required)
|
||||
OUTPUT INSERTED.id VALUES (@p1,@p2,@p3,@p4,@p5)`,
|
||||
woID, maxOrder+1, body.Title, body.Description, body.Required,
|
||||
INSERT INTO wo_steps (wo_id,step_order,title,description,required,step_type,type_config)
|
||||
OUTPUT INSERTED.id VALUES (@p1,@p2,@p3,@p4,@p5,@p6,@p7)`,
|
||||
woID, maxOrder+1, body.Title, body.Description, body.Required, body.StepType, body.TypeConfig,
|
||||
).Scan(&sid)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, err.Error())
|
||||
|
||||
@@ -56,6 +56,8 @@ type Step struct {
|
||||
Title string `db:"title" json:"title"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Required bool `db:"required" json:"required"`
|
||||
StepType string `db:"step_type" json:"step_type"`
|
||||
TypeConfig string `db:"type_config" json:"type_config"`
|
||||
Completed bool `db:"completed" json:"completed"`
|
||||
CompletedBy *string `db:"completed_by" json:"completed_by"`
|
||||
CompletedAt *time.Time `db:"completed_at" json:"completed_at"`
|
||||
@@ -166,6 +168,8 @@ type ProfileStep struct {
|
||||
Title string `db:"title" json:"title"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Required bool `db:"required" json:"required"`
|
||||
StepType string `db:"step_type" json:"step_type"`
|
||||
TypeConfig string `db:"type_config" json:"type_config"`
|
||||
}
|
||||
|
||||
// ── Users & Auth ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
-- Work Order Profiles
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = 'wo_profiles')
|
||||
BEGIN
|
||||
CREATE TABLE wo_profiles (
|
||||
id INT IDENTITY PRIMARY KEY,
|
||||
name NVARCHAR(200) NOT NULL,
|
||||
description NVARCHAR(MAX),
|
||||
category NVARCHAR(100),
|
||||
default_priority NVARCHAR(10) NOT NULL DEFAULT 'normal',
|
||||
default_duration_hours INT,
|
||||
default_instructions NVARCHAR(MAX),
|
||||
active BIT NOT NULL DEFAULT 1,
|
||||
created_at DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
|
||||
updated_at DATETIME2 NOT NULL DEFAULT GETUTCDATE()
|
||||
);
|
||||
END
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = 'wo_profile_steps')
|
||||
BEGIN
|
||||
CREATE TABLE wo_profile_steps (
|
||||
id INT IDENTITY PRIMARY KEY,
|
||||
profile_id INT NOT NULL REFERENCES wo_profiles(id) ON DELETE CASCADE,
|
||||
step_order INT NOT NULL,
|
||||
title NVARCHAR(200) NOT NULL,
|
||||
description NVARCHAR(MAX),
|
||||
required BIT NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX ix_profile_steps ON wo_profile_steps (profile_id, step_order);
|
||||
END
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Add step_type and type_config to profile steps and WO steps
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID('wo_profile_steps') AND name = 'step_type')
|
||||
ALTER TABLE wo_profile_steps ADD step_type NVARCHAR(30) NOT NULL DEFAULT 'work_step';
|
||||
-- 'work_step' | 'photo' | 'inspection' | 'note'
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID('wo_profile_steps') AND name = 'type_config')
|
||||
ALTER TABLE wo_profile_steps ADD type_config NVARCHAR(MAX) NULL;
|
||||
-- JSON; shape depends on step_type (see CLAUDE.md)
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID('wo_steps') AND name = 'step_type')
|
||||
ALTER TABLE wo_steps ADD step_type NVARCHAR(30) NOT NULL DEFAULT 'work_step';
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID('wo_steps') AND name = 'type_config')
|
||||
ALTER TABLE wo_steps ADD type_config NVARCHAR(MAX) NULL;
|
||||
Reference in New Issue
Block a user