Feat: Complete Tag & ItemTag Module Implementation - #35
Conversation
- Update repository methods to include project scope (`FindByIDAndProjectID`, `DeleteByIDAndProjectID`). - Implement `TagUseCase` with create, update, delete, and search operations. - Add unit tests for `TagUseCase` methods. - Introduce `ItemTagUseCase` for associating/disassociating tags with items.
- Extend `ProblemUseCase`, `SnippetUseCase`, and `LinkUseCase` to manage item-tag associations. - Remove all related tags during deletion of problems, snippets, and links. - Update constructors and unit tests to include `ItemTagRepository`. - Adjust API handlers and test helpers to support the new dependency.
- Add `TagHandler` to manage CRUD operations and search functionality for tags. - Introduce `ItemTagHandler` to handle tag associations and disassociations with items. - Update `router.go` and initialization logic to register new routes and handlers. - Add comprehensive unit tests for both handlers covering success and error scenarios.
- Move command structs (`CreateProblemCommand`, `UpdateProblemCommand`, etc.) to `dto` package for better reuse and consistency. - Update use cases, handlers, and tests to use the new DTO package. - Refactor logic in related use case methods (`Create`, `Update`, etc.) to map domain models to view models. - Adjust unit tests to align with the DTO-based refactor.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
- Revise local development token documentation to align with Go backend implementation. - Update token naming conventions, middleware logic, and local testing instructions. - Rewrite tag system architecture docs to reflect Go backend design, including database schema, use cases, and DTO changes.
There was a problem hiding this comment.
Actionable comments posted: 13
🧹 Nitpick comments (7)
backend-go/internal/usecase/tag_usecase_test.go (1)
417-427: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTorne explícita a expectativa do comentário.
O comentário da linha 419 afirma que
ExistsByNameAndProjectIDnão deve ser chamado. Nenhuma assertiva verifica isso. AdicionemockTagRepo.AssertNotCalledpara que o teste falhe se a comparação sem diferenciação de maiúsculas for removida.💚 Refactor proposto
assert.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, "GOLANG", result.Name) + mockTagRepo.AssertNotCalled(t, "ExistsByNameAndProjectID", ctx, "GOLANG", projectID)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/usecase/tag_usecase_test.go` around lines 417 - 427, Make the test explicitly verify the case-insensitive rename behavior by asserting mockTagRepo.AssertNotCalled for ExistsByNameAndProjectID after uc.Update completes. Keep the existing success and result assertions unchanged.backend-go/internal/usecase/item_tag_usecase.go (1)
76-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRenomeie
DisassembleTagFromItemna porta.O nome do método da porta usa "Disassemble", que significa desmontar. A operação desassocia a tag do item. O use case, o handler e a documentação usam "Disassociate". Renomeie o método da porta para
DisassociateTagFromIteme atualize o adapter e o mock embackend-go/internal/usecase/item_tag_usecase_test.go(linha 25).Remova também a linha vazia 77 antes do fechamento da função.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/usecase/item_tag_usecase.go` around lines 76 - 78, Rename the port method DisassembleTagFromItem to DisassociateTagFromItem and update all corresponding adapter and mock implementations, including the mock in item_tag_usecase_test.go, while preserving the existing use-case behavior. Remove the extra blank line before the function’s closing brace.backend-go/internal/adapter/in/web/handler/tag_handler.go (2)
43-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsidere 409 para nome de tag duplicado.
ErrTagAlreadyExistsindica conflito com um recurso existente, não payload malformado.http.StatusConflictdescreve melhor a situação e permite ao cliente distinguir falha de validação de colisão de nome. Se você adotar 409, atualize também as respostas documentadas nas linhas 2005 e 2217 debackend-go/docs/openapi.yaml.Also applies to: 156-159
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/adapter/in/web/handler/tag_handler.go` around lines 43 - 46, Atualize o tratamento de ErrTagAlreadyExists no handler de tags para retornar http.StatusConflict (409) em vez de http.StatusBadRequest, preservando a mensagem de erro existente. Ajuste também as respostas documentadas correspondentes no OpenAPI para refletir o status 409.
101-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemova a verificação inalcançável.
TagUseCase.GetByIDretornaErrTagNotFoundquando a tag não existe. Nunca retorna(nil, nil). O bloco das linhas 101-104 é código morto, já coberto pelo tratamento da linha 92.♻️ Refactor proposto
- if tag == nil { - c.JSON(http.StatusNotFound, gin.H{"error": "Tag not found"}) - return - } - c.JSON(http.StatusOK, tag)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/adapter/in/web/handler/tag_handler.go` around lines 101 - 104, Remova a verificação e o bloco de resposta para tag == nil no handler que chama TagUseCase.GetByID, pois esse caso já é tratado pelo erro ErrTagNotFound. Preserve o tratamento de erro existente e o fluxo de sucesso para tags válidas.backend-go/internal/domain/port/tag_repository.go (1)
12-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPadronize a ordem dos parâmetros UUID na interface.
FindByIDAndProjectIDeDeleteByIDAndProjectIDrecebem(projectID, id).ExistsByIDAndProjectIDrecebe(id, projectID). Os dois parâmetros sãouuid.UUID, portanto uma troca de argumentos não gera erro de compilação e produz consulta silenciosamente errada. Use a mesma ordem em todos os métodos.♻️ Refactor proposto
- ExistsByIDAndProjectID(ctx context.Context, id uuid.UUID, projectID uuid.UUID) (bool, error) + ExistsByIDAndProjectID(ctx context.Context, projectID, id uuid.UUID) (bool, error)Ajuste também o adapter em
backend-go/internal/adapter/out/persistence/tag_repository.go, o mock embackend-go/internal/usecase/tag_usecase_test.goe as chamadas embackend-go/internal/usecase/item_tag_usecase.go.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/domain/port/tag_repository.go` around lines 12 - 17, Padronize ExistsByIDAndProjectID para receber UUIDs na ordem (projectID, id), alinhando-o a FindByIDAndProjectID e DeleteByIDAndProjectID. Atualize a implementação do adapter TagRepository, o mock em TagUsecaseTest e as chamadas em ItemTagUsecase para preservar essa ordem em toda a cadeia.backend-go/internal/usecase/tag_usecase.go (1)
39-57: 🗄️ Data Integrity & Integration | 🔵 TrivialConsidere um índice único para garantir a unicidade do nome.
A verificação com
ExistsByNameAndProjectIDe oSaveposterior não são atômicos. Duas requisições concorrentes com o mesmo nome podem criar tags duplicadas no mesmo projeto. Adicione um índice único em(project_id, lower(name))na migração detagse mapeie a violação de restrição paraErrTagAlreadyExists.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/usecase/tag_usecase.go` around lines 39 - 57, A unicidade de tags ainda depende de uma verificação e gravação não atômicas. Adicione, na migração da tabela tags, um índice único para (project_id, lower(name)); atualize o fluxo de criação em torno de ExistsByNameAndProjectID e Save para capturar a violação dessa restrição e retorná-la como ErrTagAlreadyExists, preservando o tratamento existente para outros erros.backend-go/internal/adapter/out/persistence/tag_repository.go (1)
35-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePadronize o encapsulamento do erro.
Este método retorna
errsem contexto.FindAllByProjectID,SearchByNameAndProjectIDeDeleteByIDAndProjectIDno mesmo arquivo usamfmt.Errorfcom mensagem. Os adapters de snippet, link e problem também encapsulam o erro neste método.♻️ Refactor proposto
- return nil, err + return nil, fmt.Errorf("error trying to find tag: %w", err)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend-go/internal/adapter/out/persistence/tag_repository.go` around lines 35 - 46, Atualize FindByIDAndProjectID para encapsular o erro retornado por r.db.GetContext com fmt.Errorf e uma mensagem contextual, seguindo o padrão de FindAllByProjectID, SearchByNameAndProjectID, DeleteByIDAndProjectID e dos demais adapters. Preserve o tratamento de sql.ErrNoRows retornando nil, nil.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend-go/docs/openapi.yaml`:
- Around line 657-665: Restrinja o enum ItemType em OpenAPI aos tipos realmente
suportados por itemRepos: SNIPPET, LINK e PROBLEM. Atualize também as descrições
das rotas referidas para remover NOTE e CREDENTIAL ou indicar explicitamente que
ambos retornam 400 por ErrUnsupportedItemType, mantendo a documentação
consistente com validateItemOwnership.
In `@backend-go/internal/adapter/in/web/handler/item_tag_handler_test.go`:
- Around line 18-35: The HTTP response bodies returned by DoRequest remain open
in both test suites. In
backend-go/internal/adapter/in/web/handler/item_tag_handler_test.go:18-35, add
deferred resp.Body.Close() calls after every response, including responses in
subtests; apply the same cleanup to every response and flow in
backend-go/internal/adapter/in/web/handler/tag_handler_test.go:19-25.
In `@backend-go/internal/adapter/in/web/handler/tag_handler.go`:
- Line 54: Substitua as respostas diretas de model.Tag nos handlers de tag por
um DTO TagView definido em internal/dto/tag_dto.go. Adicione o mapeamento do
modelo para TagView e use-o em todos os pontos indicados do handler antes de
chamar c.JSON, preservando o contrato documentado no OpenAPI e evitando expor
novos campos do domínio.
In `@backend-go/internal/dto/tag_dto.go`:
- Line 20: Altere a validação do campo Name em UpdateTagCommand para usar min=2,
alinhando-a com CreateTagCommand e rejeitando nomes de um caractere. Atualize
também a propriedade correspondente de name em backend-go/docs/openapi.yaml para
minLength: 2.
- Around line 11-15: Atualize CreateTagCommand para tornar Color opcional,
usando um ponteiro com validação hexcolor que permita valor ausente. Ajuste
TagUsecase.Create para propagar nil como NULL e preservar o valor quando
informado, em vez de sempre criar um ponteiro para string vazia.
In `@backend-go/internal/usecase/item_tag_usecase.go`:
- Around line 122-135: Atualize validateItemsOwnership para validar cada ID
solicitado por pertencimento em existingIDs, usando uma estrutura de consulta
adequada, em vez de comparar len(existingIDs) com len(itemIDs). Preserve
ErrItemNotFound quando qualquer ID não existir e aceite IDs repetidos quando o
item correspondente existir.
In `@backend-go/internal/usecase/snippet_usecase.go`:
- Around line 159-162: Atualize os fluxos de exclusão dos métodos de use case
que removem snippets em backend-go/internal/usecase/snippet_usecase.go:159-162,
links em backend-go/internal/usecase/link_usecase.go:155-158 e problemas em
backend-go/internal/usecase/problem_usecase.go:201-204 para executar a exclusão
do item e a chamada correspondente a RemoveAllTagsFromItem na mesma transação,
confirmando a transação apenas quando ambas forem concluídas e revertendo-a em
qualquer falha.
In `@backend-go/internal/usecase/tag_usecase.go`:
- Around line 38-45: Validate sanitizedName after strings.TrimSpace in both the
create and update use cases, returning a shared ErrInvalidTagName when it is
empty before checking or persisting the tag. Declare ErrInvalidTagName with the
existing errors and map it to HTTP 400 in TagHandler.Create and
TagHandler.Update.
In `@docs/architecture/tags.md`:
- Line 57: Specify the fenced code block language as text for the route and flow
examples in the tags documentation, including the blocks at the referenced
locations, to satisfy markdownlint MD040.
- Around line 57-64: Update the supported item-type documentation near the tag
endpoints to list only SNIPPET, LINK, and PROBLEM, matching the types registered
by ItemTagUseCase. Remove NOTE and CREDENTIAL from the documented domain
constants, and add them only after their repositories are registered in
NewItemTagUseCase.
In `@docs/security/local-development-tokens.md`:
- Around line 7-10: Revise the `/api/v1/*` authentication documentation so
`dev-token` is not presented as process authentication: either describe it
explicitly as a convenience value without isolation guarantees, or document a
per-process randomly generated token and how the authorized client receives it.
- Around line 17-24: Adicione o identificador de linguagem text ou markdown ao
fence do bloco cercado na documentação, atualizando a abertura de ``` para
```text ou ```markdown e preservando o conteúdo da tabela.
- Around line 18-23: Corrija a resolução do token em main.go para que o fallback
dev-token ocorra somente quando APP_ENV=dev; em produção, exija
DEVAULTY_INTERNAL_TOKEN e retorne 401 Unauthorized quando ausente ou inválido.
Atualize a tabela de documentação para remover as referências não implementadas
a UUID gerado em memória e argumentos de linha de comando, mantendo apenas
comportamentos realmente suportados.
---
Nitpick comments:
In `@backend-go/internal/adapter/in/web/handler/tag_handler.go`:
- Around line 43-46: Atualize o tratamento de ErrTagAlreadyExists no handler de
tags para retornar http.StatusConflict (409) em vez de http.StatusBadRequest,
preservando a mensagem de erro existente. Ajuste também as respostas
documentadas correspondentes no OpenAPI para refletir o status 409.
- Around line 101-104: Remova a verificação e o bloco de resposta para tag ==
nil no handler que chama TagUseCase.GetByID, pois esse caso já é tratado pelo
erro ErrTagNotFound. Preserve o tratamento de erro existente e o fluxo de
sucesso para tags válidas.
In `@backend-go/internal/adapter/out/persistence/tag_repository.go`:
- Around line 35-46: Atualize FindByIDAndProjectID para encapsular o erro
retornado por r.db.GetContext com fmt.Errorf e uma mensagem contextual, seguindo
o padrão de FindAllByProjectID, SearchByNameAndProjectID, DeleteByIDAndProjectID
e dos demais adapters. Preserve o tratamento de sql.ErrNoRows retornando nil,
nil.
In `@backend-go/internal/domain/port/tag_repository.go`:
- Around line 12-17: Padronize ExistsByIDAndProjectID para receber UUIDs na
ordem (projectID, id), alinhando-o a FindByIDAndProjectID e
DeleteByIDAndProjectID. Atualize a implementação do adapter TagRepository, o
mock em TagUsecaseTest e as chamadas em ItemTagUsecase para preservar essa ordem
em toda a cadeia.
In `@backend-go/internal/usecase/item_tag_usecase.go`:
- Around line 76-78: Rename the port method DisassembleTagFromItem to
DisassociateTagFromItem and update all corresponding adapter and mock
implementations, including the mock in item_tag_usecase_test.go, while
preserving the existing use-case behavior. Remove the extra blank line before
the function’s closing brace.
In `@backend-go/internal/usecase/tag_usecase_test.go`:
- Around line 417-427: Make the test explicitly verify the case-insensitive
rename behavior by asserting mockTagRepo.AssertNotCalled for
ExistsByNameAndProjectID after uc.Update completes. Keep the existing success
and result assertions unchanged.
In `@backend-go/internal/usecase/tag_usecase.go`:
- Around line 39-57: A unicidade de tags ainda depende de uma verificação e
gravação não atômicas. Adicione, na migração da tabela tags, um índice único
para (project_id, lower(name)); atualize o fluxo de criação em torno de
ExistsByNameAndProjectID e Save para capturar a violação dessa restrição e
retorná-la como ErrTagAlreadyExists, preservando o tratamento existente para
outros erros.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 9ea7bf4b-7197-4380-94f6-77dc4061bb3e
📒 Files selected for processing (33)
backend-go/cmd/api/main.gobackend-go/docs/openapi.yamlbackend-go/internal/adapter/in/web/handler/item_tag_handler.gobackend-go/internal/adapter/in/web/handler/item_tag_handler_test.gobackend-go/internal/adapter/in/web/handler/link_handler.gobackend-go/internal/adapter/in/web/handler/problem_handler.gobackend-go/internal/adapter/in/web/handler/project_handler.gobackend-go/internal/adapter/in/web/handler/snippet_handler.gobackend-go/internal/adapter/in/web/handler/tag_handler.gobackend-go/internal/adapter/in/web/handler/tag_handler_test.gobackend-go/internal/adapter/in/web/handler/test_helper_test.gobackend-go/internal/adapter/in/web/router.gobackend-go/internal/adapter/out/persistence/tag_repository.gobackend-go/internal/domain/port/tag_repository.gobackend-go/internal/dto/link_dto.gobackend-go/internal/dto/problem_dto.gobackend-go/internal/dto/project_dto.gobackend-go/internal/dto/snippet_dto.gobackend-go/internal/dto/tag_dto.gobackend-go/internal/usecase/item_tag_usecase.gobackend-go/internal/usecase/item_tag_usecase_test.gobackend-go/internal/usecase/link_usecase.gobackend-go/internal/usecase/link_usecase_test.gobackend-go/internal/usecase/problem_usecase.gobackend-go/internal/usecase/problem_usecase_test.gobackend-go/internal/usecase/project_usecase.gobackend-go/internal/usecase/project_usecase_test.gobackend-go/internal/usecase/snippet_usecase.gobackend-go/internal/usecase/snippet_usecase_test.gobackend-go/internal/usecase/tag_usecase.gobackend-go/internal/usecase/tag_usecase_test.godocs/architecture/tags.mddocs/security/local-development-tokens.md
…em-tag handling - Refactor `TagUseCase` methods to return `TagView` DTOs instead of domain models. - Add mapping functions to convert domain models to DTOs (`mapTagToView`, `mapTagsToViews`) for consistency. - Extend `ItemTagUseCase` to properly handle duplicate item IDs during tag associations. - Update related tests to reflect DTO usage and improved item-tag logic. - Introduce better error logging for tag removal failures across use cases (`LinkUseCase`, `SnippetUseCase`, `ProblemUseCase`). - Modify OpenAPI spec to reflect supported item types for tag operations.
bbba5fe
into
feature/backend/refactor-to-golang
…dules (#40) * feat: integrate Tauri framework with initial splash screen, IPC commands, and automatic version synchronization script * refactor: migrate to Tauri-based packaging by bundling the backend JAR and removing legacy Java desktop components. * feat(backend-go): setup initial sql migrations and domain models" -m "- Initialize Go module (go.mod, go.sum) and project structure - Add 9 SQL database migrations mirroring Java Liquibase changesets - Add domain entity models (BaseEntity, AppSetting, Project, Snippet, Link, Problem, Note, Credential, Tag, ItemTag) - Add .gitignore for Go backend" * Feat: (GO) add repository interfaces and implement persistence layer (#30) * feat(backend-go): add repository interfaces for domain models * feat(backend-go): implement persistence layer and adapters for repositories * fix(backend-go): improve error handling and update repository method consistency - Handle `sql.ErrNoRows` in `FindByID` to return `nil` instead of error. - Standardize method naming (`ExistsById` → `ExistsByID`). - Simplify and optimize `NewPage` calculations. - Align `ItemTagRepository` methods with additional `projectID` parameter for consistency and data integrity. * Enhance backend API with project management features and documentation (#31) * feat(backend-go): add API entry point, project use case, and unit tests - Implement main.go as the entry point for the backend API - Add `ProjectUseCase` with CRUD, archive, and unarchive methods for projects - Write unit tests for the project use case with a mock repository - Update go.mod and go.sum with new dependencies for testing and validation * feat(backend-go): add project API with middleware, routing, and migrations - Extend `main.go` with server setup, project routing, and UUID token handling - Implement `ProjectHandler` for project creation and retrieval via Gin - Add CORS and auth middleware to secure and facilitate API requests - Update database migrations to use `DATETIME` for timestamps - Add validation to `CreateProjectCommand` - Update dependencies in `go.mod` and `go.sum` for API and middleware functionality * refactor(backend-go): reorganize project handler into separate package and enhance test coverage - Move `ProjectHandler` to `handler` package for better modularity - Add comprehensive test coverage for project handler, including success and failure cases - Introduce `GetAll`, `Update`, `Archive`, `Unarchive`, and `Delete` methods to `ProjectHandler` - Implement pagination support via `PaginationQuery` in `GetAll` - Adjust router and test helper to reflect structural changes * feat(backend-go): add OpenAPI documentation hosting and API reference routes - Introduce `/docs` and `/openapi.yaml` routes for hosting API documentation - Implement `registerDocsRoutes` function to serve documentation in development environment - Add dependency `go-scalar-api-reference` for generating interactive API reference - Include OpenAPI YAML specification for Devaulty API * feat(backend-go): enhance error handling, validation, and CORS middleware - Add detailed error handling in project APIs for "not found" and invalid states - Update pagination validation with binding rules for `PageNumber` and `PageSize` - Improve CORS middleware with restricted allowed origins list - Replace direct string comparisons with constant-time comparison in auth middleware - Extend OpenAPI specification with validation, error responses, and pagination constraints - Enhance test coverage for new validation and error scenarios * Feat: Complete Snippet Module Implementation, Integration Tests & API Docs (#32) * feat(backend-go): add Snippet use case with tests and repository adjustments - Implement `SnippetUseCase` for Create, Read, Update, and Delete operations. - Add unit tests for Snippet use case. - Modify repository to support project-scoped Snippet operations with `FindByIDAndProjectID` and `DeleteByIDAndProjectID`. - Refactor auxiliary functions to ensure project existence. * feat(backend-go): add SnippetHandler with tests and OpenAPI documentation - Implement SnippetHandler for Create, Read, Update, and Delete endpoints. - Add integration tests for SnippetHandler. - Extend OpenAPI documentation to include Snippet operations. - Introduce `ExtractUUIDParam` helper for parameter validation. * reafactor(backend-go): improve error handling and extend delete operations - Enhance error responses in ProjectHandler and SnippetHandler with proper status codes and logging. - Modify repository delete methods to return success status and adjust use cases accordingly. - Update integration and unit tests to validate deletion behavior and persistence. - Extend OpenAPI documentation with 500 error responses and specific error scenarios for delete endpoints. * Feat: Complete Link Module Implementation, Integration Tests & OpenAPI Documentation (#33) * reafactor(backend-go): improve error handling and extend delete operations - Enhance error responses in ProjectHandler and SnippetHandler with proper status codes and logging. - Modify repository delete methods to return success status and adjust use cases accordingly. - Update integration and unit tests to validate deletion behavior and persistence. - Extend OpenAPI documentation with 500 error responses and specific error scenarios for delete endpoints. * docs(openapi): remove nullable attribute from several fields * Feat: Complete Problem Module Implementation (#34) * feat(backend-go): implement problem use case with repository and unit tests - Added `ProblemUseCase` handling CRUD operations and business logic for problems. - Implemented `Create`, `Update`, `UpdateStatus`, `GetByID`, `GetAllByProjectID`, and `Delete` methods. - Updated `ProblemRepository` to include project-scoped methods (`FindByIDAndProjectID`, `DeleteByIDAndProjectID`, `ExistsByIDAndProjectID`). - Added comprehensive unit tests to validate problem use case functionality. * feat(backend-go): add problem handler, routes, and integration tests - Implemented `ProblemHandler` to handle HTTP operations for problems. - Added CRUD and pagination routes for problem management under `/projects/:project_id/problems`. - Extended OpenAPI documentation with schemas and endpoints for problems. - Updated integration test suite with comprehensive tests for problem API operations. - Modified `ProblemUseCase` and repository types to include summary support. * Feat: Complete Tag & ItemTag Module Implementation (#35) * feat(tag): enhance tag repository methods and add use cases - Update repository methods to include project scope (`FindByIDAndProjectID`, `DeleteByIDAndProjectID`). - Implement `TagUseCase` with create, update, delete, and search operations. - Add unit tests for `TagUseCase` methods. - Introduce `ItemTagUseCase` for associating/disassociating tags with items. * feat(usecase): integrate item-tag repository into use cases - Extend `ProblemUseCase`, `SnippetUseCase`, and `LinkUseCase` to manage item-tag associations. - Remove all related tags during deletion of problems, snippets, and links. - Update constructors and unit tests to include `ItemTagRepository`. - Adjust API handlers and test helpers to support the new dependency. * feat(handler): implement tag and item-tag HTTP handlers with tests - Add `TagHandler` to manage CRUD operations and search functionality for tags. - Introduce `ItemTagHandler` to handle tag associations and disassociations with items. - Update `router.go` and initialization logic to register new routes and handlers. - Add comprehensive unit tests for both handlers covering success and error scenarios. * refactor(dto): replace inline command structs with DTO package - Move command structs (`CreateProblemCommand`, `UpdateProblemCommand`, etc.) to `dto` package for better reuse and consistency. - Update use cases, handlers, and tests to use the new DTO package. - Refactor logic in related use case methods (`Create`, `Update`, etc.) to map domain models to view models. - Adjust unit tests to align with the DTO-based refactor. * docs: update security and tag architecture docs for Go backend - Revise local development token documentation to align with Go backend implementation. - Update token naming conventions, middleware logic, and local testing instructions. - Rewrite tag system architecture docs to reflect Go backend design, including database schema, use cases, and DTO changes. * refactor(usecase): update tag use cases to return DTOs and enhance item-tag handling - Refactor `TagUseCase` methods to return `TagView` DTOs instead of domain models. - Add mapping functions to convert domain models to DTOs (`mapTagToView`, `mapTagsToViews`) for consistency. - Extend `ItemTagUseCase` to properly handle duplicate item IDs during tag associations. - Update related tests to reflect DTO usage and improved item-tag logic. - Introduce better error logging for tag removal failures across use cases (`LinkUseCase`, `SnippetUseCase`, `ProblemUseCase`). - Modify OpenAPI spec to reflect supported item types for tag operations. * Feat: implement note module (#36) * feat(backend-go): implement project-scoped note use cases and repository updates - Update `NoteRepository` with project-scoped methods: - `FindByIDAndProjectID` - `DeleteByIDAndProjectID` - Introduce `NoteUseCase` for CRUD operations on notes, ensuring project context. - Add DTOs (`CreateNoteCommand`, `NoteView`, `NoteSummary`) for note-related operations. - Update `ItemTagUseCase` to support `ItemTypeNote`. * feat(backend-go): enhance note use cases with update and delete operations, add associated tests - Implement `NoteUseCase.Update` and `NoteUseCase.Delete` methods. - Update `NoteUseCase.GetByID` to improve error handling and tag retrieval. - Integrate `NoteRepository` into `ItemTagUseCase`. - Add mock repository for notes in tests. - Adjust `NoteView` and `NoteSummary` DTO fields for consistency. - Add unit tests for note use cases. * feat(backend-go): add NoteHandler for managing notes with full CRUD operations - Implement `NoteHandler` for handling notes within project context. - Add router mappings and integrate `NoteHandler` into the API. - Update test helpers and add extensive tests for note routes and handler logic. * feat(api-docs): add OpenAPI documentation for notes management - Document CRUD operations for notes: create, read (single and paginated), update, and delete. - Add schemas for `Note`, `NoteSummary`, `NoteSummaryPage`, `CreateNoteCommand`, and `UpdateNoteCommand`. - Extend `ItemType` enum with `NOTE`. - Define paths for `/projects/{project_id}/notes` and `/projects/{project_id}/notes/{note_id}`. * fix(backend-go): improve error logging in NoteHandler and update OpenAPI docs for NOTE item type - Log detailed error information in `NoteHandler.Create` on internal server errors. - Extend OpenAPI `ItemType` descriptions to include support for `NOTE` in tag association endpoints. * feat: Vault Security Engine & AppSettings (#37) * feat(backend-go): implement secure vault use case and key management - Add VaultUseCase to manage master password setup, unlocking, and session status. - Introduce MasterKeySession and Argon2KeyDeriver adapters for secure key handling. - Add DTOs for handling API interactions related to the vault and app settings. - Implement unit tests for VaultUseCase methods. - Upgrade dependencies in go.mod and go.sum for crypto and security improvements. * feat(backend-go): add SecurityHandler and integrate Vault APIs - Introduce SecurityHandler to manage master password setup, unlocking, session status, and vault locking. - Extend Gin router with security-related routes. - Update DTO validation for master password constraints. - Add OpenAPI documentation for security endpoints. - Implement unit tests for SecurityHandler functions. - Refactor memory hygiene guide to align with backend-go security standards. * refactor(backend-go): improve memory handling and add comprehensive security tests - Enhance memory hygiene in SecurityHandler by ensuring proper password reference clearing. - Add extensive unit tests for Argon2KeyDeriver and MasterKeySessionHolder for key derivation, salt generation, and session management. - Simplify VaultUseCase by consolidating app setting save operations with `SaveMasterPasswordSettings`. - Improve synchronization and defensive copying in MasterKeySessionHolder. - Introduce transaction handling and constraints for saving master password settings in AppSettingRepository. * Feat: Credentials Module Implementation & AES-256-GCM Security Integration (#38) * feat(backend-go): implement AES-GCM crypto adapter and related DTOs - Add AES-GCM encryption/decryption implementation (`AESGCMCryptoAdapter`) - Create Crypto port interface for encryption abstraction - Include tests for AES-GCM encryption/decryption scenarios - Add credential-related DTOs for command and view models - Update `CredentialRepositoryAdapter` to refine query for credential retrieval * **feat(backend-go): add credential use case with unit tests and repository enhancements** - Implement `CredentialUseCase` for CRUD operations, including: - `Create`, `GetById`, `GetAllByProjectID`, `Update`, and `Delete`. - Add corresponding unit tests to ensure robustness. - Extend `CredentialRepository` interface for project-scoped queries. - Update `CredentialRepositoryAdapter` with project-specific operations for `FindByID` and `DeleteByID`. * **feat(backend-go): add CredentialHandler and API routes for credential management** - Introduced `CredentialHandler` with CRUD operations (`Create`, `GetAll`, `GetById`, `Update`, `Delete`). - Mapped routes under `/projects/:project_id/credentials`. - Updated dependency injection for `CredentialHandler` in `main.go`. - Enhanced test coverage with integration tests for credential APIs. * **feat(backend-go): add VaultAutoLock scheduler to purge expired sessions** - Introduced `VaultAutoLock` in the `scheduler` package to handle automatic session purging. - Integrated the scheduler into `main.go` for periodic cleanup of expired sessions. - Refactored `MasterKeySession` field casing for consistency across the codebase. * **feat: extend OpenAPI spec to include credential management and secret payload handling** - Added schemas for `CredentialSecretType`, `CreateCredentialCommand`, `UpdateCredentialCommand`, `CredentialView`, and paginated responses. - Documented new endpoints under `/projects/{project_id}/credentials` for CRUD operations. - Updated handling for item types to support `CREDENTIAL`. - Improved sensitive data marshaling using `SecretBytes` for enhanced memory hygiene. * **refactor(backend-go): improve test memory hygiene and update credential update logic** - Refactored unit tests to ensure zeroing of sensitive `masterKey` during runtime. - Updated `UpdateCredential` to handle partial updates with secret payload merging. - Improved error messages for decryption failure scenarios. - Adjusted OpenAPI spec error description for clarity on UUID validation. * Feature/adapt frontend to golang (#39) * feat(frontend): adapt REST API client to Go backend - Update internal security token header to DEVAULTY_INTERNAL_TOKEN - Adapt error interceptor to handle Go backend error payload format ({ error: string }) - Align MasterPassword setup check response with MasterPasswordSetupRequiredView schema - Update tag search query parameter to tag_name - Add tag badges rendering and tag search filtering to Snippets list view * feat(tauri): integrate native Go backend and optimize memory usage - Replace Java JRE integration in Tauri Rust shell with native Go sidecar execution - Implement secure IPC using CSPRNG UUID token and stdout stream handshake - Embed SQL migrations inside Go binary via go:embed for a self-contained executable - Reduce Go backend RAM footprint down to 19MB via Gin ReleaseMode and GOGC tuning - Implement 3-phase app startup (handshake, HTTP health check, minimum 2s splash screen) - Update cross-platform build scripts and purge all remaining Java/Spring dependencies * refactor: migrate backend from Gradle/Java to Go and update CI/CD pipelines to build installers via Tauri * fix: improve backend data directory resolution, clean build artifacts, and normalize application versioning for Tauri compatibility. * refactor!: replace Java backend with native Go backend and update Tauri v2 pipeline
Summary
This Pull Request introduces the complete Tag and ItemTag management modules for the Go backend, porting and enhancing the tag functionality from the original backend.
It includes:
✨ Key Changes
🏗️ 1. Centralized DTO Architecture (
internal/dto/)Centralized all Command and View DTOs into the
internal/dtopackage:tag_dto.gosnippet_dto.golink_dto.goproblem_dto.goproject_dto.goTagSummaryIntroduced a lightweight DTO containing:
idnamecolorUsed in:
SnippetViewLinkViewProblemViewProblemSummaryto avoid overfetching during item retrieval.
TagAdded the full Tag DTO containing:
idprojectIdnamecolorcreatedAtupdatedAtUsed for Tag CRUD operations.
⚙️ 2. Domain & Persistence (
internal/domain/,internal/adapter/out/persistence/)Added new domain models:
TagItemTagIntroduced the
ItemTypeenum:SNIPPETNOTELINKPROBLEMCREDENTIALCreated repository ports:
TagRepositoryItemTagRepositoryImplemented SQLite persistence using
jmoiron/sqlxwith:🧠 3. Use Cases (
internal/usecase/)TagUseCaseImplemented:
CreateGetByIDGetAllByProjectIDSearchByNameUpdateDeleteFeatures include:
400 Bad Request)ItemTagUseCaseImplemented:
AssociateTagToItemDisassociateTagFromItemValidates ownership of both the target item and tag before creating associations.
Automatic Tag Loading
Updated:
SnippetUseCaseLinkUseCaseProblemUseCaseto automatically attach
[]TagSummaryto:GetByIDUpdateGetAllByProjectIDresponses.
Cascading Cleanup
When a Snippet, Link, or Problem is deleted, all associated tag relationships are automatically removed using
RemoveAllTagsFromItem.🌐 4. Web Layer (
internal/adapter/in/web/)TagHandlerAdded endpoints for:
ItemTagHandlerAdded endpoints for:
PUT)DELETE)Router
Updated
router.goto ensure literal routes (such as/search) take precedence over wildcard routes (/:tag_id).📚 5. OpenAPI 3.0 Documentation
Updated
docs/openapi.yamlwith:Schemas
TagTagSummaryCreateTagCommandUpdateTagCommandItemTypeUpdated existing schemas:
SnippetLinkProblemProblemSummaryto include:
Documented all Tag and ItemTag endpoints.
🌐 New API Endpoints
POST/api/v1/projects/:project_id/tagsGET/api/v1/projects/:project_id/tagsGET/api/v1/projects/:project_id/tags/search?tag_name=)GET/api/v1/projects/:project_id/tags/:tag_idPATCH/api/v1/projects/:project_id/tags/:tag_idDELETE/api/v1/projects/:project_id/tags/:tag_idPUT/api/v1/projects/:project_id/items/:item_type/:item_id/tags/:tag_idDELETE/api/v1/projects/:project_id/items/:item_type/:item_id/tags/:tag_id🧪 Testing & Verification
Unit Tests
Updated:
tag_usecase_test.gosnippet_usecase_test.golink_usecase_test.goproblem_usecase_test.goIntegration Tests
Added:
tag_handler_test.go(28 test cases)item_tag_handler_test.go(16 test cases)Test Results
Run the complete test suite:
go test -count=1 ./...Result:
Summary by CodeRabbit