Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
90eb87d
feat: add transactional repository methods (InsertWithTx, CheckLimits…
alexgarzao Mar 20, 2026
76a99cb
docs: add rule to exclude test results from commit messages
alexgarzao Mar 20, 2026
2435817
docs: explain why CheckLimitsWithTx tests do not assert db propagation
alexgarzao Mar 20, 2026
ed49de2
fix: correct seed reference in collision comment (401 -> 104)
alexgarzao Mar 20, 2026
433cddb
docs: remove orphan section 4.1.1 references from LimitUsageDetail
alexgarzao Mar 20, 2026
e856af9
fix: deep copy nested Scopes slice in ToValidationResponse
alexgarzao Mar 20, 2026
308f2cf
Merge remote-tracking branch 'origin/develop' into feat/idempotency-k…
alexgarzao Mar 20, 2026
f21584c
style: remove inconsistent t.Parallel from InsertWithTx subtests
alexgarzao Mar 20, 2026
33ef5d7
fix: annotate span on nil validation in insertInternal
alexgarzao Mar 20, 2026
af3a057
refactor: use pgdb.ErrNilConnection sentinel in InsertWithTx
alexgarzao Mar 20, 2026
3048748
refactor: add operationName parameter to insertInternal for dynamic l…
alexgarzao Mar 20, 2026
fa47d4e
chore(ci): bump shared workflows to v1.18.1 and add shared_paths
bedatty Mar 20, 2026
0c8b7bc
fix(ci): add explicit nonroot user and skip gitops on empty builds
bedatty Mar 20, 2026
83a7d85
refactor: address code review findings for T-002
alexgarzao Mar 20, 2026
c915e90
Merge branch 'feat/idempotency-key-support--transactional-repository-…
alexgarzao Mar 20, 2026
669c3fe
feat: add HashUUIDToInt32 utility for advisory lock keys
alexgarzao Mar 20, 2026
845ff31
feat: add ValidateResult and duplicate detection in Validate flow
alexgarzao Mar 20, 2026
0f287ff
feat: return HTTP 201 for new validations, 200 for duplicates
alexgarzao Mar 20, 2026
c500a3c
test: add idempotency unit tests for deduplication flow
alexgarzao Mar 20, 2026
2ee77cc
test: update existing tests for ValidateResult return type
alexgarzao Mar 20, 2026
384472a
style: replace task ID references with descriptive comments
alexgarzao Mar 20, 2026
7ab3f88
refactor: reject nil validation before acquiring DB connection
alexgarzao Mar 23, 2026
1b21be6
fix: suppress gosec G115 for deliberate uint32-to-int32 conversion
alexgarzao Mar 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,24 @@ on:

jobs:
build:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/build.yml@v1.15.0
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/build.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
enable_dockerhub: true
enable_ghcr: true
dockerhub_org: lerianstudio
enable_gitops_artifacts: true
shared_paths: |
go.mod
go.sum
pkg/
Makefile
secrets: inherit

update_gitops:
needs: [build]
if: needs.build.result == 'success'
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/gitops-update.yml@v1.17.0
if: needs.build.result == 'success' && needs.build.outputs.has_builds == 'true'
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/gitops-update.yml@v1.18.1
with:
runner_type: "firmino-lxc-runners"
artifact_pattern: "gitops-tags-tracer"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/go-combined-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:
jobs:
go-analysis:
name: Go Analysis
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/go-pr-analysis.yml@v1.17.0
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/go-pr-analysis.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
app_name_prefix: "tracer"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gptchangelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
changelog:
# Run if: manual trigger OR Release workflow succeeded
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/gptchangelog.yml@v1.17.0
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/gptchangelog.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
# No filter_paths = single app mode (non-monorepo)
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/pr-security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ on:

jobs:
security-scan:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.17.0
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-security-scan.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
dockerhub_org: "lerianstudio"
shared_paths: |
go.mod
go.sum
pkg/
Makefile
secrets: inherit
2 changes: 1 addition & 1 deletion .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions:

jobs:
validate:
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-validation.yml@v1.13.1
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/pr-validation.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
pr_title_types: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:
jobs:
release:
name: Create Release
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.17.0
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.18.1
with:
runner_type: "blacksmith-4vcpu-ubuntu-2404"
secrets: inherit
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ WORKDIR /app
COPY --from=builder /app/tracer /app/tracer
COPY --from=builder /tracer/migrations /app/migrations

# distroless:nonroot already runs as non-root user (uid 65532)
# Explicitly set non-root user for Docker Hub health score compliance
USER nonroot:nonroot

EXPOSE 8080 7001

Expand Down
2 changes: 1 addition & 1 deletion api/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2660,7 +2660,7 @@ const docTemplate = `{
"type": "string"
},
"scope": {
"description": "Scope is a human-readable string representation of the limit's scope\n(e.g., \"account:uuid\" or \"segment:uuid\" or \"global\").\nPer section 4.1.1.",
"description": "Scope is a human-readable string representation of the limit's scope\n(e.g., \"account:uuid\" or \"segment:uuid\" or \"global\").",
"type": "string"
},
"skipReason": {
Expand Down
1 change: 0 additions & 1 deletion api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2399,7 +2399,6 @@ components:
description: |-
Scope is a human-readable string representation of the limit's scope
(e.g., "account:uuid" or "segment:uuid" or "global").
Per section 4.1.1.
type: string
skipReason:
description: |-
Expand Down
2 changes: 1 addition & 1 deletion api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2658,7 +2658,7 @@
"type": "string"
},
"scope": {
"description": "Scope is a human-readable string representation of the limit's scope\n(e.g., \"account:uuid\" or \"segment:uuid\" or \"global\").\nPer section 4.1.1.",
"description": "Scope is a human-readable string representation of the limit's scope\n(e.g., \"account:uuid\" or \"segment:uuid\" or \"global\").",
"type": "string"
},
"skipReason": {
Expand Down
1 change: 0 additions & 1 deletion api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ definitions:
description: |-
Scope is a human-readable string representation of the limit's scope
(e.g., "account:uuid" or "segment:uuid" or "global").
Per section 4.1.1.
type: string
skipReason:
description: |-
Expand Down
2 changes: 2 additions & 0 deletions docs/PROJECT_RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3174,6 +3174,7 @@ otel.SetTracerProvider(tp) // Set global provider for lib-commons
13. **Priority-based rule evaluation** - All rules evaluated, DENY precedence
14. **Direct OTel attribute/codes imports** - Use lib-commons wrappers (SetSpanAttributesFromStruct, HandleSpanError)
15. **Unstructured logging** - Use `WithFields` instead of `Infof`/`Errorf` with string interpolation (see [Structured Logging](#structured-logging))
16. **Task/ticket IDs in code** - Never reference task IDs (T-001, JIRA-123, etc.) in source code, comments, or test names. Code must be self-explanatory without project management context. Use descriptive names instead.

---

Expand All @@ -3185,3 +3186,4 @@ otel.SetTracerProvider(tp) // Set global provider for lib-commons
2. **NEVER run `git push` without explicit user approval**
3. **NEVER modify files outside the scope of the requested task**
4. **Always ask for confirmation before destructive operations**
5. **NEVER include test execution results in commit messages** - Do not mention test counts, pass/fail status, or coverage numbers. Commit messages describe *what* changed and *why*, not verification results.
5 changes: 3 additions & 2 deletions internal/adapters/http/in/mocks/validation_service_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions internal/adapters/http/in/validation_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/gofiber/fiber/v2"
"go.opentelemetry.io/otel/trace"

"tracer/internal/services"
"tracer/pkg/clock"
"tracer/pkg/constant"
"tracer/pkg/logging"
Expand All @@ -31,7 +32,7 @@ const maxPayloadSize = 100 * 1024
// ValidationService defines the interface for validation operations.
// Interface defined locally per Ring pattern.
type ValidationService interface {
Validate(ctx context.Context, request *model.ValidationRequest) (*model.ValidationResponse, error)
Validate(ctx context.Context, request *model.ValidationRequest) (*services.ValidateResult, error)
}

// ValidationHandler handles HTTP requests for transaction validation.
Expand Down Expand Up @@ -147,19 +148,25 @@ func (h *ValidationHandler) Validate(c *fiber.Ctx) error {
}

// Call validation service
response, err := h.service.Validate(ctx, &request)
result, err := h.service.Validate(ctx, &request)
if err != nil {
return h.handleValidationError(c, &span, err)
}

logger.WithFields(
"operation", "handler.validations.validate",
"request.id", request.RequestID.String(),
"decision", string(response.Decision),
"processing_time_ms", response.ProcessingTimeMs,
"decision", string(result.Response.Decision),
"processing_time_ms", result.Response.ProcessingTimeMs,
"is_duplicate", result.IsDuplicate,
).Info("Validation completed")

return libHTTP.OK(c, response)
// Return HTTP 201 for new requests, HTTP 200 for duplicate (idempotent) requests (DD-9)
if result.IsDuplicate {
return libHTTP.OK(c, result.Response)
}

return libHTTP.Created(c, result.Response)
}

// validationErrorMapping maps validation errors to their specific error codes and messages.
Expand Down
Loading
Loading