feat: Add project foundation, documentation, and Docker setup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jan Novak
2026-01-19 19:49:47 +01:00
commit a59ef0f3f5
10 changed files with 1020 additions and 0 deletions

116
backend/claude.md Normal file
View File

@@ -0,0 +1,116 @@
## General
- Before scaffolding any service, verify current stable versions from official sources (go.dev, rust-lang.org, nodejs.org, etc.)
- Prefer stdlib over dependencies where reasonable
- No vendoring unless explicitly requested
## Go
- Use latest stable Go version (check https://go.dev/dl/ before starting)
- Use `slog` for structured logging
- `context.Context` first param, always
- No `init()` unless unavoidable
- Errors: prefer `errors.Join` for multiple errors, `fmt.Errorf` with `%w` for wrapping
## Containers
- Multi-stage builds, distroless/scratch final images
- ubuntu based images for the development builds
- Non-root user, read-only rootfs for production builds
- prepare dockerfiles for both development and production
- Pin base image digests in prod Dockerfiles
## K8s Manifests
- Always include resource requests/limits
- Liveness/readiness probes with sane defaults
- PodDisruptionBudgets for replicated workloads
## Code Style
- Fail fast, return early
- Table-driven tests
- No obvious comments
## CI/CD
- Git remote: Gitea at https://[gitea.yourdomain.com](https://gitea.home.hrajfrisbee.cz/)
- CI: Gitea Actions (workflow syntax is GitHub Actions compatible)
- Workflows go in `.gitea/workflows/`
- Use `runs-on: linux-amd64` (or whatever labels your runners have)
- Registry: gitea.home.hrajfrisbee.cz (use `${{ secrets.REGISTRY_TOKEN }}` for auth)
## Testing (Go)
### Go Test Requirements
- **MANDATORY: All new Go code must have corresponding tests**
- Use stdlib `testing` package, no testify unless already in project
- Table-driven tests as default pattern
- Test file next to source: `foo.go``foo_test.go`
- Name tests `Test<Function>_<scenario>` (e.g., `TestCreateUser_duplicateEmail`)
- Use `t.Parallel()` where safe
- Subtests for table entries: `t.Run(tc.name, func(t *testing.T) { ... })`
- Test behavior, not implementation
- Use `testing.Short()` to skip slow integration tests: `if testing.Short() { t.Skip() }`
### Test Structure
- Each test function should test ONE behavior
- Use descriptive test names: `TestExerciseHandler_Create_ValidInput`
- Table-driven test format:
```go
tests := []struct {
name string
input InputType
want ExpectedType
wantErr bool
}{
{"valid input", validInput, expectedOutput, false},
{"empty name", emptyName, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// test logic
})
}
```
### Handler Tests (Unit)
- Mock external dependencies (repositories, services)
- Use `httptest.NewRecorder()` and `httptest.NewRequest()`
- Test: success path, validation errors, not found, internal errors
- Mock interfaces defined in `internal/api/interfaces.go`
- Mock implementations in `internal/api/mocks_test.go`
### Repository Tests (Integration)
- Use testcontainers-go for database tests
- Integration tests in `_test.go` with build tag `//go:build integration`
- Clean database state between tests using `truncateTables()`
- Test: CRUD operations, edge cases, transactions, cascades
- Test helpers in `internal/storage/testhelpers_test.go`
### What to Test
- All public functions/methods
- Happy path AND error paths
- Edge cases: empty inputs, nil values, not found
- Validation logic
- Transaction rollback scenarios
### What NOT to Test
- Simple getters/setters
- Third-party library code
- Private helper functions (test through public API)
### Running Tests
```bash
# Run all unit tests (fast)
go test ./...
# Run with verbose output
go test -v ./...
# Run with coverage
go test -cover ./...
# Run only unit tests, skip integration
go test -short ./...
# Run integration tests (requires Docker)
go test -v -tags=integration ./internal/storage/...
# Run specific package
go test -v ./internal/api/...
```