Compare commits
	
		
			2 Commits
		
	
	
		
			4c68612ea0
			...
			aba4f850b7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| aba4f850b7 | |||
| a8e3332723 | 
							
								
								
									
										24
									
								
								.gitea/workflows/build.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.gitea/workflows/build.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | name: Backend Build and Test | ||||||
|  | on: [push] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: standard-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout | ||||||
|  |         uses: actions/checkout@v4 | ||||||
|  |  | ||||||
|  |       - name: Setup Go | ||||||
|  |         uses: actions/setup-go@v5 | ||||||
|  |         with: | ||||||
|  |           go-version: '>=1.24' | ||||||
|  |  | ||||||
|  |       - name: Build | ||||||
|  |         run: | | ||||||
|  |           cd backend | ||||||
|  |           go build . | ||||||
|  |  | ||||||
|  |       - name: Test | ||||||
|  |         run: | | ||||||
|  |           cd backend | ||||||
|  |           go test . -v | ||||||
							
								
								
									
										25
									
								
								.gitea/workflows/deploy.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								.gitea/workflows/deploy.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | name: Backend Deploy | ||||||
|  | on: | ||||||
|  |   push: [main] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: standard-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout | ||||||
|  |         uses: actions/checkout@v4 | ||||||
|  |  | ||||||
|  |       - name: Login | ||||||
|  |         with: | ||||||
|  |           package_rw: ${{ secrets.PACKAGE_RW }} | ||||||
|  |         run: docker login gitea.seeseepuff.be -u seeseemelk -p ${{ secrets.PACKAGE_RW }} | ||||||
|  |  | ||||||
|  |       - name: Build | ||||||
|  |         run: | | ||||||
|  |           cd backend | ||||||
|  |           docker build -t gitea.seeseepuff.be/seeseemelk/wolproxy:$(git rev-parse --short HEAD) . | ||||||
|  |  | ||||||
|  |       - name: Push | ||||||
|  |         run: | | ||||||
|  |           cd backend | ||||||
|  |           docker push gitea.seeseepuff.be/seeseemelk/wolproxy:$(git rev-parse --short HEAD) | ||||||
							
								
								
									
										14
									
								
								backend/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								backend/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | FROM golang:1.24.2-alpine3.21 | ||||||
|  |  | ||||||
|  | WORKDIR /app | ||||||
|  | COPY go.mod go.sum ./ | ||||||
|  | RUN go mod download | ||||||
|  |  | ||||||
|  | COPY migrations ./migrations/ | ||||||
|  | COPY *.go ./ | ||||||
|  | COPY *.gohtml ./ | ||||||
|  | RUN go build -o /allowance_planner | ||||||
|  |  | ||||||
|  | EXPOSE 8080 | ||||||
|  | ENV GIN_MODE=release | ||||||
|  | CMD ["/allowance_planner"] | ||||||
| @@ -516,6 +516,7 @@ func TestPutAllowanceById(t *testing.T) { | |||||||
| 		"name":   TestAllowanceName, | 		"name":   TestAllowanceName, | ||||||
| 		"target": 5000, | 		"target": 5000, | ||||||
| 		"weight": 10, | 		"weight": 10, | ||||||
|  | 		"colour": "#FF5733", | ||||||
| 	} | 	} | ||||||
| 	resp := e.POST("/user/1/allowance").WithJSON(requestBody).Expect().Status(201).JSON().Object() | 	resp := e.POST("/user/1/allowance").WithJSON(requestBody).Expect().Status(201).JSON().Object() | ||||||
| 	allowanceId := int(resp.Value("id").Number().Raw()) | 	allowanceId := int(resp.Value("id").Number().Raw()) | ||||||
| @@ -525,6 +526,7 @@ func TestPutAllowanceById(t *testing.T) { | |||||||
| 		"name":   "Updated Allowance", | 		"name":   "Updated Allowance", | ||||||
| 		"target": 6000, | 		"target": 6000, | ||||||
| 		"weight": 15, | 		"weight": 15, | ||||||
|  | 		"colour": "#3357FF", | ||||||
| 	} | 	} | ||||||
| 	e.PUT("/user/1/allowance/" + strconv.Itoa(allowanceId)).WithJSON(updateRequest).Expect().Status(200) | 	e.PUT("/user/1/allowance/" + strconv.Itoa(allowanceId)).WithJSON(updateRequest).Expect().Status(200) | ||||||
|  |  | ||||||
| @@ -534,6 +536,7 @@ func TestPutAllowanceById(t *testing.T) { | |||||||
| 	result.Value("name").IsEqual("Updated Allowance") | 	result.Value("name").IsEqual("Updated Allowance") | ||||||
| 	result.Value("target").IsEqual(6000) | 	result.Value("target").IsEqual(6000) | ||||||
| 	result.Value("weight").IsEqual(15) | 	result.Value("weight").IsEqual(15) | ||||||
|  | 	result.Value("colour").IsEqual("#3357FF") | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestCompleteTask(t *testing.T) { | func TestCompleteTask(t *testing.T) { | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								backend/colour.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								backend/colour.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func ConvertStringToColour(colourStr string) (int, error) { | ||||||
|  | 	if len(colourStr) == 0 { | ||||||
|  | 		return 0xFF0000, nil // Default colour if no string is provided | ||||||
|  | 	} | ||||||
|  | 	if colourStr[0] == '#' { | ||||||
|  | 		colourStr = colourStr[1:] | ||||||
|  | 	} | ||||||
|  | 	if len(colourStr) != 6 && len(colourStr) != 3 { | ||||||
|  | 		return 0, errors.New("colour must be a valid hex string") | ||||||
|  | 	} | ||||||
|  | 	var colour int | ||||||
|  | 	_, err := fmt.Sscanf(colourStr, "%x", &colour) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, fmt.Errorf("invalid colour format: %v", err) | ||||||
|  | 	} | ||||||
|  | 	if len(colourStr) == 3 { | ||||||
|  | 		r := (colour & 0xF00) >> 8 | ||||||
|  | 		g := (colour & 0x0F0) >> 4 | ||||||
|  | 		b := (colour & 0x00F) >> 0 | ||||||
|  | 		colour = (r << 16 << 4) | (g << 8 << 4) | (b << 0 << 4) | ||||||
|  | 	} | ||||||
|  | 	return colour, nil | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								backend/colour_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								backend/colour_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestConvertStringToColourWithSign(t *testing.T) { | ||||||
|  | 	colour, err := ConvertStringToColour("#123456") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 0x123456, colour) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestConvertStringToColourWithoutSign(t *testing.T) { | ||||||
|  | 	colour, err := ConvertStringToColour("123456") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 0x123456, colour) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestConvertStringToColourWithSignThreeDigits(t *testing.T) { | ||||||
|  | 	colour, err := ConvertStringToColour("#ABC") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 0xA0B0C0, colour) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestConvertStringToColourWithoutSignThreeDigits(t *testing.T) { | ||||||
|  | 	colour, err := ConvertStringToColour("ABC") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 0xA0B0C0, colour) | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ package main | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"math" | 	"math" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -112,12 +113,13 @@ func (db *Db) GetUserAllowanceById(userId int, allowanceId int) (*Allowance, err | |||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		var target, progress int64 | 		var target, progress, colour int64 | ||||||
| 		err := db.db.Query("select id, name, target, balance, weight from allowances where user_id = ? and id = ?"). | 		err := db.db.Query("select id, name, target, balance, weight, colour from allowances where user_id = ? and id = ?"). | ||||||
| 			Bind(userId, allowanceId). | 			Bind(userId, allowanceId). | ||||||
| 			ScanSingle(&allowance.ID, &allowance.Name, &target, &progress, &allowance.Weight) | 			ScanSingle(&allowance.ID, &allowance.Name, &target, &progress, &allowance.Weight, &colour) | ||||||
| 		allowance.Target = float64(target) / 100.0 | 		allowance.Target = float64(target) / 100.0 | ||||||
| 		allowance.Progress = float64(progress) / 100.0 | 		allowance.Progress = float64(progress) / 100.0 | ||||||
|  | 		allowance.Colour = fmt.Sprintf("#%06X", colour) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| @@ -141,9 +143,15 @@ func (db *Db) CreateAllowance(userId int, allowance *CreateAllowanceRequest) (in | |||||||
| 	} | 	} | ||||||
| 	defer tx.MustRollback() | 	defer tx.MustRollback() | ||||||
|  |  | ||||||
|  | 	// Convert string colour to a valid hex format | ||||||
|  | 	colour, err := ConvertStringToColour(allowance.Colour) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Insert the new allowance | 	// Insert the new allowance | ||||||
| 	err = tx.Query("insert into allowances (user_id, name, target, weight) values (?, ?, ?, ?)"). | 	err = tx.Query("insert into allowances (user_id, name, target, weight, colour) values (?, ?, ?, ?, ?)"). | ||||||
| 		Bind(userId, allowance.Name, int(math.Round(allowance.Target*100.0)), allowance.Weight). | 		Bind(userId, allowance.Name, int(math.Round(allowance.Target*100.0)), allowance.Weight, colour). | ||||||
| 		Exec() | 		Exec() | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -255,9 +263,14 @@ func (db *Db) UpdateAllowance(userId int, allowanceId int, allowance *UpdateAllo | |||||||
| 	} | 	} | ||||||
| 	defer tx.MustRollback() | 	defer tx.MustRollback() | ||||||
|  |  | ||||||
|  | 	colour, err := ConvertStringToColour(allowance.Colour) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	target := int(math.Round(allowance.Target * 100.0)) | 	target := int(math.Round(allowance.Target * 100.0)) | ||||||
| 	err = tx.Query("update allowances set name=?, target=?, weight=? where id = ? and user_id = ?"). | 	err = tx.Query("update allowances set name=?, target=?, weight=?, colour=? where id = ? and user_id = ?"). | ||||||
| 		Bind(allowance.Name, target, allowance.Weight, allowanceId, userId). | 		Bind(allowance.Name, target, allowance.Weight, colour, allowanceId, userId). | ||||||
| 		Exec() | 		Exec() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -36,18 +36,21 @@ type Allowance struct { | |||||||
| 	Target   float64 `json:"target"` | 	Target   float64 `json:"target"` | ||||||
| 	Progress float64 `json:"progress"` | 	Progress float64 `json:"progress"` | ||||||
| 	Weight   float64 `json:"weight"` | 	Weight   float64 `json:"weight"` | ||||||
|  | 	Colour   string  `json:"colour"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type CreateAllowanceRequest struct { | type CreateAllowanceRequest struct { | ||||||
| 	Name   string  `json:"name"` | 	Name   string  `json:"name"` | ||||||
| 	Target float64 `json:"target"` | 	Target float64 `json:"target"` | ||||||
| 	Weight float64 `json:"weight"` | 	Weight float64 `json:"weight"` | ||||||
|  | 	Colour string  `json:"colour"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type UpdateAllowanceRequest struct { | type UpdateAllowanceRequest struct { | ||||||
| 	Name   string  `json:"name"` | 	Name   string  `json:"name"` | ||||||
| 	Target float64 `json:"target"` | 	Target float64 `json:"target"` | ||||||
| 	Weight float64 `json:"weight"` | 	Weight float64 `json:"weight"` | ||||||
|  | 	Colour string  `json:"colour"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type BulkUpdateAllowanceRequest struct { | type BulkUpdateAllowanceRequest struct { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								backend/migrations/2_add_colour.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								backend/migrations/2_add_colour.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | alter table allowances | ||||||
|  | add column colour integer not null; | ||||||
		Reference in New Issue
	
	Block a user