diff --git a/backend/api_test.go b/backend/api_test.go
index 33e7082..a5eaf29 100644
--- a/backend/api_test.go
+++ b/backend/api_test.go
@@ -594,6 +594,82 @@ func TestCompleteTask(t *testing.T) {
 	}
 }
 
+func TestCompleteTaskAllowanceWeightsSumTo0(t *testing.T) {
+	e := startServer(t)
+	taskId := createTestTaskWithAmount(e, 101)
+
+	e.GET("/tasks").Expect().Status(200).JSON().Array().Length().IsEqual(1)
+
+	// Update rest allowance
+	e.PUT("/user/1/allowance/0").WithJSON(UpdateAllowanceRequest{
+		Weight: 0,
+	}).Expect().Status(200)
+	// Create two allowance goals
+	e.POST("/user/1/allowance").WithJSON(CreateAllowanceRequest{
+		Name:   "Test Allowance 1",
+		Target: 1000,
+		Weight: 0,
+	}).Expect().Status(201)
+
+	// Complete the task
+	e.POST("/task/" + strconv.Itoa(taskId) + "/complete").Expect().Status(200)
+
+	// Verify the task is marked as completed
+	e.GET("/task/" + strconv.Itoa(taskId)).Expect().Status(404)
+
+	// Verify the allowances are updated for user 1
+	allowances := e.GET("/user/1/allowance").Expect().Status(200).JSON().Array()
+	allowances.Length().IsEqual(2)
+	allowances.Value(0).Object().Value("id").Number().IsEqual(0)
+	allowances.Value(0).Object().Value("progress").Number().IsEqual(101)
+	allowances.Value(1).Object().Value("id").Number().IsEqual(1)
+	allowances.Value(1).Object().Value("progress").Number().IsEqual(0)
+}
+
+func TestCompleteTaskInvalidId(t *testing.T) {
+	e := startServer(t)
+	e.POST("/task/999/complete").Expect().Status(404)
+}
+
+func TestCompleteAllowance(t *testing.T) {
+	e := startServer(t)
+	createTestTaskWithAmount(e, 100)
+
+	// Create allowance goal
+	e.POST("/user/1/allowance").WithJSON(CreateAllowanceRequest{
+		Name:   "Test Allowance 1",
+		Target: 100,
+		Weight: 50,
+	}).Expect().Status(201)
+
+	// Complete the task
+	e.POST("/task/1/complete").Expect().Status(200)
+
+	// Complete allowance goal
+	e.POST("/user/1/allowance/1/complete").Expect().Status(200)
+
+	// Verify the allowance no longer exists
+	e.GET("/user/1/allowance/1").Expect().Status(404)
+
+	// Verify history is updated
+	history := e.GET("/user/1/history").Expect().Status(200).JSON().Array()
+	history.Length().IsEqual(2)
+	history.Value(0).Object().Value("allowance").Number().IsEqual(100)
+	history.Value(0).Object().Value("timestamp").String().AsDateTime().InRange(getDelta(time.Now(), 2.0))
+	history.Value(1).Object().Value("allowance").Number().IsEqual(-100)
+	history.Value(1).Object().Value("timestamp").String().AsDateTime().InRange(getDelta(time.Now(), 2.0))
+}
+
+func TestCompleteAllowanceInvalidUserId(t *testing.T) {
+	e := startServer(t)
+	e.POST("/user/999/allowance/1/complete").Expect().Status(404)
+}
+
+func TestCompleteAllowanceInvalidAllowanceId(t *testing.T) {
+	e := startServer(t)
+	e.POST("/user/1/allowance/999/complete").Expect().Status(404)
+}
+
 func getDelta(base time.Time, delta float64) (time.Time, time.Time) {
 	start := base.Add(-time.Duration(delta) * time.Second)
 	end := base.Add(time.Duration(delta) * time.Second)
diff --git a/backend/db.go b/backend/db.go
index 7f9feff..100040c 100644
--- a/backend/db.go
+++ b/backend/db.go
@@ -175,6 +175,39 @@ func (db *Db) DeleteAllowance(userId int, allowanceId int) error {
 	return nil
 }
 
+func (db *Db) CompleteAllowance(userId int, allowanceId int) error {
+	tx, err := db.db.Begin()
+	if err != nil {
+		return err
+	}
+	defer tx.MustRollback()
+
+	// Get the cost of the allowance
+	var cost int
+	err = tx.Query("select balance from allowances where id = ? and user_id = ?").
+		Bind(allowanceId, userId).ScanSingle(&cost)
+	if err != nil {
+		return err
+	}
+
+	// Delete the allowance
+	err = tx.Query("delete from allowances where id = ? and user_id = ?").
+		Bind(allowanceId, userId).Exec()
+	if err != nil {
+		return err
+	}
+
+	// Add a history entry
+	err = tx.Query("insert into history (user_id, timestamp, amount) values (?, ?, ?)").
+		Bind(userId, time.Now().Unix(), -cost).
+		Exec()
+	if err != nil {
+		return err
+	}
+
+	return tx.Commit()
+}
+
 func (db *Db) UpdateUserAllowance(userId int, allowance *UpdateAllowanceRequest) error {
 	tx, err := db.db.Begin()
 	if err != nil {
@@ -356,24 +389,26 @@ func (db *Db) CompleteTask(taskId int) error {
 
 		remainingReward := reward
 
-		// Distribute the reward to the allowances
-		for allowanceRow := range tx.Query("select id, weight from allowances where user_id = ? and weight > 0").Bind(userId).Range(&err) {
-			var allowanceId int
-			var allowanceWeight float64
-			err = allowanceRow.Scan(&allowanceId, &allowanceWeight)
-			if err != nil {
-				return err
-			}
+		if sumOfWeights > 0 {
+			// Distribute the reward to the allowances
+			for allowanceRow := range tx.Query("select id, weight from allowances where user_id = ? and weight > 0").Bind(userId).Range(&err) {
+				var allowanceId int
+				var allowanceWeight float64
+				err = allowanceRow.Scan(&allowanceId, &allowanceWeight)
+				if err != nil {
+					return err
+				}
 
-			// Calculate the amount to add to the allowance
-			amount := int((allowanceWeight / sumOfWeights) * float64(remainingReward))
-			sumOfWeights -= allowanceWeight
-			err = tx.Query("update allowances set balance = balance + ? where id = ? and user_id = ?").
-				Bind(amount, allowanceId, userId).Exec()
-			if err != nil {
-				return err
+				// Calculate the amount to add to the allowance
+				amount := int((allowanceWeight / sumOfWeights) * float64(remainingReward))
+				sumOfWeights -= allowanceWeight
+				err = tx.Query("update allowances set balance = balance + ? where id = ? and user_id = ?").
+					Bind(amount, allowanceId, userId).Exec()
+				if err != nil {
+					return err
+				}
+				remainingReward -= amount
 			}
-			remainingReward -= amount
 		}
 
 		// Add the remaining reward to the user
diff --git a/backend/main.go b/backend/main.go
index 8e1f510..512bdf3 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -287,6 +287,49 @@ func putUserAllowance(c *gin.Context) {
 	c.IndentedJSON(http.StatusOK, gin.H{"message": "Allowance updated successfully"})
 }
 
+func completeAllowance(c *gin.Context) {
+	userIdStr := c.Param("userId")
+	allowanceIdStr := c.Param("allowanceId")
+
+	userId, err := strconv.Atoi(userIdStr)
+	if err != nil {
+		log.Printf(ErrInvalidUserID+": %v", err)
+		c.JSON(http.StatusBadRequest, gin.H{"error": ErrInvalidUserID})
+		return
+	}
+
+	allowanceId, err := strconv.Atoi(allowanceIdStr)
+	if err != nil {
+		log.Printf("Invalid allowance ID: %v", err)
+		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid allowance ID"})
+		return
+	}
+
+	exists, err := db.UserExists(userId)
+	if err != nil {
+		log.Printf(ErrCheckingUserExist, err)
+		c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError})
+		return
+	}
+	if !exists {
+		c.JSON(http.StatusNotFound, gin.H{"error": ErrUserNotFound})
+		return
+	}
+
+	err = db.CompleteAllowance(userId, allowanceId)
+	if errors.Is(err, mysqlite.ErrNoRows) {
+		c.JSON(http.StatusNotFound, gin.H{"error": "Allowance not found"})
+		return
+	}
+	if err != nil {
+		log.Printf("Error completing allowance: %v", err)
+		c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError})
+		return
+	}
+
+	c.IndentedJSON(http.StatusOK, gin.H{"message": "Allowance completed successfully"})
+}
+
 func createTask(c *gin.Context) {
 	var taskRequest CreateTaskRequest
 	if err := c.ShouldBindJSON(&taskRequest); err != nil {
@@ -518,6 +561,7 @@ func start(ctx context.Context, config *ServerConfig) {
 	router.GET("/api/user/:userId/allowance/:allowanceId", getUserAllowanceById)
 	router.DELETE("/api/user/:userId/allowance/:allowanceId", deleteUserAllowance)
 	router.PUT("/api/user/:userId/allowance/:allowanceId", putUserAllowance)
+	router.POST("/api/user/:userId/allowance/:allowanceId/complete", completeAllowance)
 	router.POST("/api/tasks", createTask)
 	router.GET("/api/tasks", getTasks)
 	router.GET("/api/task/:taskId", getTask)
@@ -558,5 +602,9 @@ func main() {
 		Datasource: os.Getenv("DB_PATH"),
 		Addr:       ":8080",
 	}
+	if config.Datasource == "" {
+		config.Datasource = "allowance_planner.db3"
+		log.Printf("Warning: No DB_PATH set, using default of %s", config.Datasource)
+	}
 	start(context.Background(), &config)
 }
diff --git a/backend/migrations/1_initial.sql b/backend/migrations/1_initial.sql
index c787888..d400ec8 100644
--- a/backend/migrations/1_initial.sql
+++ b/backend/migrations/1_initial.sql
@@ -2,7 +2,7 @@ create table users
 (
     id   integer primary key,
     name text not null,
-    weight real not null default 1.0,
+    weight real not null default 0.0,
     balance integer not null default 0
 ) strict;