Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
4ff1797
docs: add email service design spec
fiqrikm18 Jul 9, 2026
ccc28e2
chore: add .worktrees to gitignore
fiqrikm18 Jul 9, 2026
8aa9683
email: add domain interface and config
fiqrikm18 Jul 9, 2026
92bf2eb
fix: use conditional defaults for email config
fiqrikm18 Jul 9, 2026
13112a1
email: add console provider and factory
fiqrikm18 Jul 9, 2026
c123ba0
fix: remove out-of-scope stubs and add trailing newlines
fiqrikm18 Jul 9, 2026
0410836
email: add SMTP provider
fiqrikm18 Jul 9, 2026
bf5b1fe
fix: correct SMTP URL construction and add tests
fiqrikm18 Jul 9, 2026
5973902
email: add SendGrid provider
fiqrikm18 Jul 9, 2026
3e6d2e6
fix: improve SendGrid provider with tests and error handling
fiqrikm18 Jul 9, 2026
561dad0
email: add HTML templates for verification, reset, welcome, invite
fiqrikm18 Jul 9, 2026
a5f5179
email: add template rendering to all providers
fiqrikm18 Jul 9, 2026
d3728f7
test: add template renderer tests
fiqrikm18 Jul 9, 2026
caa2505
auth: add email verification and password reset fields to user entity
fiqrikm18 Jul 9, 2026
bd60e5e
fix: improve user repository with tests and DRY queries
fiqrikm18 Jul 9, 2026
e068e04
auth: add email verification and password reset flows
fiqrikm18 Jul 9, 2026
e992032
fix: add auth service tests, remove unused field, use sentinel errors
fiqrikm18 Jul 9, 2026
3742a31
auth: add verification and password reset HTTP endpoints
fiqrikm18 Jul 9, 2026
1144dbd
test: add HTTP handler tests for verification and reset endpoints
fiqrikm18 Jul 9, 2026
f0ac5ce
auth: wire email module into Fx container
fiqrikm18 Jul 9, 2026
e7e2fd3
email: add provider tests
fiqrikm18 Jul 9, 2026
87dce11
docs: sqlc repository migration design spec
fiqrikm18 Jul 9, 2026
6b8f259
test: strengthen email provider tests with content and type assertions
fiqrikm18 Jul 9, 2026
f319a80
fix: close security gaps in email verification flow
fiqrikm18 Jul 9, 2026
ad2d518
docs: move sqlc design spec out of email branch (scope separation)
fiqrikm18 Jul 9, 2026
4fda3a5
Merge feature/email-service: email service with verification and pass…
fiqrikm18 Jul 9, 2026
71e0acb
docs: sqlc repository migration design spec
fiqrikm18 Jul 9, 2026
8b1b983
fix: SMTP STARTTLS, token hashing, template caching, zap logger for C…
fiqrikm18 Jul 10, 2026
1b19bd6
Merge fix/email-deferred-issues: SMTP STARTTLS, token hashing, templa…
fiqrikm18 Jul 10, 2026
c8ecdc8
docs: sqlc repository migration implementation plan
fiqrikm18 Jul 10, 2026
c3d7e74
feat: configure multi-domain sqlc with 5 generation targets
fiqrikm18 Jul 10, 2026
de404fd
fix: remove pqtype dependency, add jsonb→[]byte override in sqlc
fiqrikm18 Jul 10, 2026
9398930
feat(todo): migrate todo repository from database/sql to sqlc
fiqrikm18 Jul 10, 2026
1119a66
feat(authentication): migrate user and refresh_token repositories fro…
fiqrikm18 Jul 10, 2026
072cd12
feat(authorization): migrate role, permission, role_permission, user_…
fiqrikm18 Jul 10, 2026
f876885
feat(user): migrate user repository from database/sql to sqlc
fiqrikm18 Jul 10, 2026
f4ffbfd
feat(auditlog): migrate auditlog repository from database/sql to sqlc…
fiqrikm18 Jul 10, 2026
1a976c7
fix(auditlog): replace uuid.MustParse with uuid.Parse to avoid panics…
fiqrikm18 Jul 10, 2026
44ed128
docs: event-driven email implementation plan
fiqrikm18 Jul 10, 2026
9fc08cf
feat(events): extract EventBus interface, rename InMemoryEventBus
fiqrikm18 Jul 10, 2026
200e1df
feat(auth): add domain events and email event handler
fiqrikm18 Jul 10, 2026
72d738a
feat(auth): replace direct mailer calls with event publishing
fiqrikm18 Jul 10, 2026
2323b9b
feat(todo): wire event publishing in command handlers
fiqrikm18 Jul 10, 2026
6db7fbc
feat(http): unified response envelope, MapError, middleware cleanup
fiqrikm18 Jul 10, 2026
7f5833c
feat(handlers): use MapError, standardized codes, RespondPaginated fo…
fiqrikm18 Jul 10, 2026
d008548
chore: update Fx wiring for shared EventBus and email handler
fiqrikm18 Jul 10, 2026
a1b98df
docs: update architecture, folder structure, and API docs
fiqrikm18 Jul 10, 2026
3022817
docs(readme): add event-driven email, unified response, user endpoint…
fiqrikm18 Jul 10, 2026
4ed1fdd
feat(events): add LoggingEventBus decorator and propagate handler errors
fiqrikm18 Jul 10, 2026
0d45d7f
docs: document LoggingEventBus event error handling
fiqrikm18 Jul 10, 2026
0b3de0a
feat(telemetry): add HTTP tracing middleware, trace IDs in logs, span…
fiqrikm18 Jul 10, 2026
b015d3e
ci/cd: production Dockerfile, docker-compose.prod, GitHub Actions, K8…
fiqrikm18 Jul 10, 2026
1e303b2
docs(swagger): update annotations to use utils.APIResponse and regene…
fiqrikm18 Jul 11, 2026
71cead3
chore(utils): add PaginatedPayload and PaginatedResult types
fiqrikm18 Jul 11, 2026
cb7bdc6
feat(middleware): add response formatter middleware
fiqrikm18 Jul 11, 2026
0788d94
feat(router): wire response formatter middleware
fiqrikm18 Jul 11, 2026
9fcdd8d
feat(httpadapter): add pure-function handler adapters
fiqrikm18 Jul 11, 2026
19c0eaa
refactor(handlers): use utils.Handle* helpers in authz and user handlers
fiqrikm18 Jul 11, 2026
404f442
refactor(handlers): use utils.Handle* helpers in auth/todo, add plan …
fiqrikm18 Jul 11, 2026
a4f7d5d
fix: enterprise hardening fixes
fiqrikm18 Jul 11, 2026
2abff99
docs: add multi-tenancy design spec with user data normalization
fiqrikm18 Jul 12, 2026
ebc21b9
feat(multitenancy): add config, context keys, and tenant resolver mid…
fiqrikm18 Jul 12, 2026
5b42535
feat(multitenancy): add multi-tenancy with row-level isolation and us…
fiqrikm18 Jul 12, 2026
0e3e25b
refactor(tenant): use sqlc for persistence layer like other domains
fiqrikm18 Jul 12, 2026
d368242
docs: add CQRS standardization design spec
fiqrikm18 Jul 12, 2026
b02128b
feat(cqrs): add CommandBus and QueryBus with in-memory implementations
fiqrikm18 Jul 12, 2026
7b45cdc
refactor(authorization): migrate to CQRS with CommandBus/QueryBus
fiqrikm18 Jul 12, 2026
143119b
refactor(user): migrate to CQRS with CommandBus/QueryBus
fiqrikm18 Jul 12, 2026
7805454
refactor(tenant): migrate to CQRS with CommandBus/QueryBus
fiqrikm18 Jul 12, 2026
76a96d5
Task 5: Rewrite auth handler tests to use bus dispatch pattern
fiqrikm18 Jul 12, 2026
58d7460
Task 6-7: Migrate todo module to CQRS bus + update main.go wiring
fiqrikm18 Jul 12, 2026
0c65d65
Task 8: Remove dead code (old application service directories)
fiqrikm18 Jul 12, 2026
07c8cf1
fix: migration script
fiqrikm18 Jul 12, 2026
c4d9d5d
fix: UpdateUser sqlc query uses WHERE deleted_at IS NULL and excludes…
fiqrikm18 Jul 13, 2026
81d5021
feat: add shared cursor package for cursor-based pagination
fiqrikm18 Jul 13, 2026
289094b
feat: add CursorMeta, RespondCursorPaginated, update formatter
fiqrikm18 Jul 13, 2026
be7f0f0
refactor: remove pagination queries from sqlc, keep only CRUD
fiqrikm18 Jul 13, 2026
c7d304c
feat: migrate user repository CRUD (GetByID, Update, Delete) to sqlc
fiqrikm18 Jul 13, 2026
0074230
feat: migrate todo repository CRUD (Create, GetByID, Update, Delete) …
fiqrikm18 Jul 13, 2026
aad0184
feat: update repository interfaces for cursor pagination
fiqrikm18 Jul 13, 2026
9810aab
feat: implement cursor pagination in all repository implementations
fiqrikm18 Jul 13, 2026
e4b4f88
docs: error hardening design spec
fiqrikm18 Jul 13, 2026
cb6cae7
Casbin standard table, cursor pagination, sqlc migration, error harde…
fiqrikm18 Jul 13, 2026
a2de89f
CI: fix golangci-lint config, update Go 1.25, add sqlc+swagger genera…
fiqrikm18 Jul 13, 2026
2228f98
Fix golangci-lint: shadow is a govet analyzer, not standalone linter
fiqrikm18 Jul 13, 2026
3d1672d
CI: build golangci-lint from source with Go 1.25
fiqrikm18 Jul 13, 2026
1559c38
fix: error checking
fiqrikm18 Jul 13, 2026
3ba04ca
chore: add script install hook and precommit
fiqrikm18 Jul 13, 2026
8b38233
deploy: change go version
fiqrikm18 Jul 13, 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
49 changes: 49 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Git
.git
.gitignore

# Documentation
docs/*.md
*.md

# Build artifacts
bin/
*.exe
*.dll
*.so
*.dylib

# Test artifacts
coverage.out
coverage.html
*.test

# Local environment
.env
.env.local
.env.*.local

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Docker
Dockerfile*
docker-compose*.yml
.dockerignore

# CI/CD
.github/
k8s/

# Temporary
tmp/
temp/
*.tmp
92 changes: 92 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: CD

on:
push:
branches:
- main
tags:
- 'v*.*.*'

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
name: Build and Push Docker Image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Check failure on line 26 in .github/workflows/cd.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=IDTS-LAB_go-codebase&issues=AZ9cH5qBOFmXP_NXJoKU&open=AZ9cH5qBOFmXP_NXJoKU&pullRequest=1

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3

Check failure on line 29 in .github/workflows/cd.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=IDTS-LAB_go-codebase&issues=AZ9cH5qBOFmXP_NXJoKV&open=AZ9cH5qBOFmXP_NXJoKV&pullRequest=1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5

Check failure on line 37 in .github/workflows/cd.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=IDTS-LAB_go-codebase&issues=AZ9cH5qBOFmXP_NXJoKW&open=AZ9cH5qBOFmXP_NXJoKW&pullRequest=1
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v6

Check failure on line 47 in .github/workflows/cd.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=IDTS-LAB_go-codebase&issues=AZ9cH5qBOFmXP_NXJoKX&open=AZ9cH5qBOFmXP_NXJoKX&pullRequest=1
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: build-and-push
if: github.ref == 'refs/heads/main'
environment:
name: staging
url: https://staging.go-codebase.example.com
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Deploy to staging
run: |
echo "Deploying to staging environment..."
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
# Add your staging deployment commands here
# Example: ssh, kubectl, helm, or webhook

deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: build-and-push
if: startsWith(github.ref, 'refs/tags/v')
environment:
name: production
url: https://go-codebase.example.com
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Deploy to production
run: |
echo "Deploying to production environment..."
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}"
# Add your production deployment commands here
# Example: ssh, kubectl, helm, or webhook
153 changes: 153 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: CI

on:
push:
branches:
- main
- development
pull_request:
branches:
- main
- development

env:
GO_VERSION: "1.25"

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Download dependencies
run: go mod download

- name: Generate code
run: |
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/swaggo/swag/cmd/swag@latest
make sqlc
make swagger

- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

- name: Run golangci-lint
run: golangci-lint run --timeout=5m

test:
name: Test
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: go_codebase_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Download dependencies
run: go mod download

- name: Generate code
run: |
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/swaggo/swag/cmd/swag@latest
make sqlc
make swagger

- name: Run tests
env:
DB_HOST: localhost
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: postgres
DB_NAME: go_codebase_test
DB_SSLMODE: disable
REDIS_ADDR: localhost:6379
JWT_SECRET: test-secret-key-not-for-production
run: go test -race -count=1 ./...

build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Download dependencies
run: go mod download

- name: Generate code
run: |
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/swaggo/swag/cmd/swag@latest
make sqlc
make swagger

- name: Build binary
run: go build -o bin/server ./cmd/api

- name: Build Docker image
run: docker build -t go-codebase:${{ github.sha }} .
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ vendor/
docs/docs.go
docs/swagger.json
docs/swagger.yaml
.worktrees

# SQLc generated code (regenerate with `make sqlc`)
**/infrastructure/persistence/sqlc/
internal/shared/auditlog/sqlc/
4 changes: 3 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
run:
timeout: 5m
go: "1.24"

linters:
enable:
Expand All @@ -17,7 +18,8 @@ linters:

linters-settings:
govet:
check-shadowing: true
enable:
- shadow
revive:
rules:
- name: exported
Expand Down
27 changes: 23 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
FROM golang:1.22-alpine AS builder
# Build stage
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git
RUN apk add --no-cache git ca-certificates tzdata

WORKDIR /app

# Copy dependency files first for better layer caching
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server ./cmd/api
# Build the binary
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/server ./cmd/api

# Final stage
FROM alpine:3.19

RUN apk --no-cache add ca-certificates tzdata
RUN apk --no-cache add ca-certificates tzdata curl

# Create non-root user
RUN addgroup -g 1000 appgroup && \
adduser -u 1000 -G appgroup -s /bin/sh -D appuser

WORKDIR /app

# Copy binary and required files
COPY --from=builder /app/server .
COPY --from=builder /app/configs ./configs
COPY --from=builder /app/migrations ./migrations

# Change ownership to non-root user
RUN chown -R appuser:appgroup /app

USER appuser

EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1

CMD ["./server"]
Loading
Loading