Replace status_id with in_progress boolean field
- Remove task_statuses lookup table and StatusID foreign key - Add InProgress boolean field to Task model - Add database migration (005_replace_status_with_in_progress) - Update all handlers, services, and repositories - Update admin frontend to display in_progress as checkbox/boolean - Remove Task Statuses tab from admin lookups page - Update tests to use InProgress instead of StatusID - Task categorization now uses InProgress for kanban column assignment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,7 +32,8 @@ func TestIntegration_ContractorSharingFlow(t *testing.T) {
|
||||
var residenceResp map[string]interface{}
|
||||
err := json.Unmarshal(w.Body.Bytes(), &residenceResp)
|
||||
require.NoError(t, err)
|
||||
residenceCID := residenceResp["id"].(float64)
|
||||
residenceData := residenceResp["data"].(map[string]interface{})
|
||||
residenceCID := residenceData["id"].(float64)
|
||||
|
||||
// ========== User A shares residence C with User B ==========
|
||||
// Generate share code
|
||||
@@ -191,7 +192,8 @@ func TestIntegration_ContractorAccessWithoutResidenceShare(t *testing.T) {
|
||||
|
||||
var residenceResp map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &residenceResp)
|
||||
residenceID := residenceResp["id"].(float64)
|
||||
residenceData := residenceResp["data"].(map[string]interface{})
|
||||
residenceID := residenceData["id"].(float64)
|
||||
|
||||
// User A creates a contractor tied to the residence (NOT shared with User B)
|
||||
contractorBody := map[string]interface{}{
|
||||
@@ -235,9 +237,10 @@ func TestIntegration_ContractorUpdateAndDeleteAccess(t *testing.T) {
|
||||
w := app.makeAuthenticatedRequest(t, "POST", "/api/residences", residenceBody, userAToken)
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
var residenceResp map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &residenceResp)
|
||||
residenceID := residenceResp["id"].(float64)
|
||||
var residenceResp2 map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &residenceResp2)
|
||||
residenceData2 := residenceResp2["data"].(map[string]interface{})
|
||||
residenceID := residenceData2["id"].(float64)
|
||||
|
||||
// Share with User B
|
||||
w = app.makeAuthenticatedRequest(t, "POST", "/api/residences/"+formatID(residenceID)+"/generate-share-code", nil, userAToken)
|
||||
@@ -259,9 +262,9 @@ func TestIntegration_ContractorUpdateAndDeleteAccess(t *testing.T) {
|
||||
w = app.makeAuthenticatedRequest(t, "POST", "/api/contractors", contractorBody, userAToken)
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
var contractorResp map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &contractorResp)
|
||||
contractorID := contractorResp["id"].(float64)
|
||||
var contractorResp3 map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &contractorResp3)
|
||||
contractorID3 := contractorResp3["id"].(float64)
|
||||
|
||||
// User B (with access) can update the contractor
|
||||
// Note: Must include residence_id to keep it tied to the residence
|
||||
@@ -269,7 +272,7 @@ func TestIntegration_ContractorUpdateAndDeleteAccess(t *testing.T) {
|
||||
"name": "Updated by User B",
|
||||
"residence_id": uint(residenceID),
|
||||
}
|
||||
w = app.makeAuthenticatedRequest(t, "PUT", "/api/contractors/"+formatID(contractorID), updateBody, userBToken)
|
||||
w = app.makeAuthenticatedRequest(t, "PUT", "/api/contractors/"+formatID(contractorID3), updateBody, userBToken)
|
||||
assert.Equal(t, http.StatusOK, w.Code, "User B should be able to update contractor in shared residence")
|
||||
|
||||
// User C (without access) cannot update the contractor
|
||||
@@ -277,15 +280,15 @@ func TestIntegration_ContractorUpdateAndDeleteAccess(t *testing.T) {
|
||||
"name": "Hacked by User C",
|
||||
"residence_id": uint(residenceID),
|
||||
}
|
||||
w = app.makeAuthenticatedRequest(t, "PUT", "/api/contractors/"+formatID(contractorID), updateBody2, userCToken)
|
||||
w = app.makeAuthenticatedRequest(t, "PUT", "/api/contractors/"+formatID(contractorID3), updateBody2, userCToken)
|
||||
assert.Equal(t, http.StatusForbidden, w.Code, "User C should NOT be able to update contractor")
|
||||
|
||||
// User C cannot delete the contractor
|
||||
w = app.makeAuthenticatedRequest(t, "DELETE", "/api/contractors/"+formatID(contractorID), nil, userCToken)
|
||||
w = app.makeAuthenticatedRequest(t, "DELETE", "/api/contractors/"+formatID(contractorID3), nil, userCToken)
|
||||
assert.Equal(t, http.StatusForbidden, w.Code, "User C should NOT be able to delete contractor")
|
||||
|
||||
// User B (with access) can delete the contractor
|
||||
w = app.makeAuthenticatedRequest(t, "DELETE", "/api/contractors/"+formatID(contractorID), nil, userBToken)
|
||||
w = app.makeAuthenticatedRequest(t, "DELETE", "/api/contractors/"+formatID(contractorID3), nil, userBToken)
|
||||
assert.Equal(t, http.StatusOK, w.Code, "User B should be able to delete contractor in shared residence")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user