Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ updates:
- "/uiprojector"
- "/trace"
- "/storage"
- "/notifications"
- "/json"
- "/xmlgen"
- "/htmlgen"
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,41 @@ jobs:
- name: Run Tests (includes build)
run: go test -v -race -coverprofile=coverage.out -covermode=atomic ./...

# The notifications/ package is its own Go module, so the root ./... jobs above do not
# cover it. Run its quality checks and tests independently.
notifications-module:
name: Notifications Module
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: notifications
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-go@v7
with:
go-version-file: 'notifications/go.mod'
cache-dependency-path: notifications/go.sum
cache: true

- name: Verify go.mod
run: |
go mod tidy
git diff --exit-code go.mod go.sum

- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.11.2
args: --timeout=5m
working-directory: notifications

- name: Run Tests (includes build)
run: go test -v -race -coverprofile=coverage.out -covermode=atomic ./...

# The uiprojector/ package is its own Go module, so the root ./... jobs above do not
# cover it. Run its quality checks and tests independently.
uiprojector-module:
Expand Down
50 changes: 25 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,30 @@ This SDK provides all the infrastructure pieces to build such a system, while ke

## Packages

| Package | Purpose |
|------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`artifact`](artifact/README.md) | Versioned configuration registry — load workflow definitions, form schemas, and templates by ID (includes [`artifact/adapter`](artifact/adapter/README.md), bridge adapters for domain types) |
| [`authn`](authn/README.md) | JWT validation, identity context injection, and HTTP middleware |
| [`authz`](authz/README.md) | Scope-based authorization middleware and predicates, decoupled from authn |
| [`configyaml`](configyaml/README.md) | Loads a YAML config file into a Go struct, resolving `{{env:NAME}}` / `{{file:/path}}` placeholders via `secret.SecretRef` |
| [`cors`](cors/README.md) | CORS HTTP middleware |
| [`database`](database/README.md) | `database/sql` connection factory (PostgreSQL, MySQL, SQLite) with pooling and health checks |
| [`htmlgen`](htmlgen/README.md) | Print-ready HTML document generation from a static template and structured data, with contextual escaping |
| [`httputil`](httputil/README.md) | Shared HTTP response helpers for JSON payloads and correlation-ID-tagged API error bodies |
| [`json`](json/README.md) | Packages for working with decoded JSON documents (includes [`json/jsonpointer`](json/jsonpointer/README.md), RFC 6901 JSON Pointer get/set) |
| [`notification`](notification/README.md) | Multi-channel notification router (SMS, email) with pluggable providers |
| [`pagination`](pagination/README.md) | Standard pagination envelope and query parameter parsing |
| [`payment`](payment/README.md) | Pluggable payment gateway orchestration with webhook processing and idempotency |
| [`remote`](remote/README.md) | Registry-based outbound HTTP client with pluggable auth (API key, Bearer, OAuth2) |
| [`secret`](secret/README.md) | Secret-bearing config values (`SecretRef`) resolved from env, file, or literal sources |
| [`shared`](shared/README.md) | Small, dependency-free helpers (deep copy, nested map access, config validation) used across other modules |
| [`storage`](storage/README.md) | File storage abstraction (local filesystem and AWS S3) with presigned URLs |
| [`taskflow`](taskflow/README.md) | Micro-interactive task orchestration — the core engine for human-in-the-loop steps |
| [`temporal`](temporal/README.md) | Temporal client factory |
| [`trace`](trace/README.md) | HTTP request trace propagation and context-based trace ID correlation |
| [`uiprojector`](uiprojector/README.md) | Zone-based, metadata-driven UI rendering from workflow state and business data |
| [`workflow`](workflow/README.md) | JSON DSL-driven Temporal workflow graph interpreter |
| [`xmlgen`](xmlgen/README.md) | XML document generation from a static template and structured data, with automatic escaping |
| Package | Purpose |
|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`artifact`](artifact/README.md) | Versioned configuration registry — load workflow definitions, form schemas, and templates by ID (includes [`artifact/adapter`](artifact/adapter/README.md), bridge adapters for domain types) |
| [`authn`](authn/README.md) | JWT validation, identity context injection, and HTTP middleware |
| [`authz`](authz/README.md) | Scope-based authorization middleware and predicates, decoupled from authn |
| [`configyaml`](configyaml/README.md) | Loads a YAML config file into a Go struct, resolving `{{env:NAME}}` / `{{file:/path}}` placeholders via `secret.SecretRef` |
| [`cors`](cors/README.md) | CORS HTTP middleware |
| [`database`](database/README.md) | `database/sql` connection factory (PostgreSQL, MySQL, SQLite) with pooling and health checks |
| [`htmlgen`](htmlgen/README.md) | Print-ready HTML document generation from a static template and structured data, with contextual escaping |
| [`httputil`](httputil/README.md) | Shared HTTP response helpers for JSON payloads and correlation-ID-tagged API error bodies |
| [`json`](json/README.md) | Packages for working with decoded JSON documents (includes [`json/jsonpointer`](json/jsonpointer/README.md), RFC 6901 JSON Pointer get/set) |
| [`notifications`](notifications/README.md) | Multi-channel notification router (SMS, email) with pluggable providers |
| [`pagination`](pagination/README.md) | Standard pagination envelope and query parameter parsing |
| [`payment`](payment/README.md) | Pluggable payment gateway orchestration with webhook processing and idempotency |
| [`remote`](remote/README.md) | Registry-based outbound HTTP client with pluggable auth (API key, Bearer, OAuth2) |
| [`secret`](secret/README.md) | Secret-bearing config values (`SecretRef`) resolved from env, file, or literal sources |
| [`shared`](shared/README.md) | Small, dependency-free helpers (deep copy, nested map access, config validation) used across other modules |
| [`storage`](storage/README.md) | File storage abstraction (local filesystem and AWS S3) with presigned URLs |
| [`taskflow`](taskflow/README.md) | Micro-interactive task orchestration — the core engine for human-in-the-loop steps |
| [`temporal`](temporal/README.md) | Temporal client factory |
| [`trace`](trace/README.md) | HTTP request trace propagation and context-based trace ID correlation |
| [`uiprojector`](uiprojector/README.md) | Zone-based, metadata-driven UI rendering from workflow state and business data |
| [`workflow`](workflow/README.md) | JSON DSL-driven Temporal workflow graph interpreter |
| [`xmlgen`](xmlgen/README.md) | XML document generation from a static template and structured data, with automatic escaping |

## Requirements

Expand Down Expand Up @@ -76,7 +76,7 @@ flowchart TD
P["USER_INPUT · PAYMENT · EXTERNAL_REVIEW · API_CALL · custom"]
end

SS["payment · remote · notification · storage"]
SS["payment · remote · notifications · storage"]
AR[("artifact registry<br>workflow defs · task templates<br>form schemas · render templates")]

Portal -->|HTTP| server
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.26.0

require (
github.com/OpenNSW/core/remote v0.8.0
github.com/OpenNSW/core/secret v0.2.0
github.com/OpenNSW/core/shared v0.3.0
github.com/OpenNSW/core/uiprojector v0.3.0
github.com/aws/aws-sdk-go-v2 v1.47.1
Expand All @@ -21,6 +20,7 @@ require (
)

require (
github.com/OpenNSW/core/secret v0.2.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.20.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.4 // indirect
Expand Down
10 changes: 8 additions & 2 deletions notification/README.md → notifications/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# notification
# notifications

`github.com/OpenNSW/core/notifications` is its own Go module. It moved from `github.com/OpenNSW/core/notification` in the root module. The package is still named `notification`, so only the import path changes; code keeps using `notification.X`. Import it with the name written out, as `goimports` writes it when a package's name differs from its path:

```go
import notification "github.com/OpenNSW/core/notifications"
```

A multi-channel notification router with a pluggable provider model. Your application registers one provider per channel type (email, SMS, etc.); the manager dispatches each `Request` to the correct provider at runtime.

## Usage

```go
import "github.com/OpenNSW/core/notification"
import notification "github.com/OpenNSW/core/notifications"

manager, err := notification.NewManager(
notification.Config{
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions notifications/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/OpenNSW/core/notifications

go 1.26

require (
github.com/OpenNSW/core/remote v0.8.0
github.com/OpenNSW/core/secret v0.2.0
)
12 changes: 12 additions & 0 deletions notifications/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/OpenNSW/core/remote v0.8.0 h1:Ot44DtkEtzqKffy77EI0S6BCH1xDspQ2y2lSFKcZpPg=
github.com/OpenNSW/core/remote v0.8.0/go.mod h1:BzfC7ppzEAd5fUQmIsgeR2lZ6LzygNU4prNjvDpDH+4=
github.com/OpenNSW/core/secret v0.2.0 h1:7kxJYbVNJhN9X9/YyTUci4bv9oYKcm0nT/wBVrxBChQ=
github.com/OpenNSW/core/secret v0.2.0/go.mod h1:MEkX9vnlPRVTn+JQQsb192PoY6p3hbFSOIV+FxIMrc0=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"fmt"
"net/http"

"github.com/OpenNSW/core/notification"
notification "github.com/OpenNSW/core/notifications"
"github.com/OpenNSW/core/remote"
"github.com/OpenNSW/core/remote/auth"
"github.com/OpenNSW/core/secret"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"fmt"
"net/http"

"github.com/OpenNSW/core/notification"
notification "github.com/OpenNSW/core/notifications"
"github.com/OpenNSW/core/remote"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"testing"
"time"

"github.com/OpenNSW/core/notification"
"github.com/OpenNSW/core/notification/providers"
notification "github.com/OpenNSW/core/notifications"
"github.com/OpenNSW/core/notifications/providers"
)

func TestSMSIntegration(t *testing.T) {
Expand Down
File renamed without changes.
Loading