From eaffcaf885d6e2a536bb5ff15b19e7d3c424b026 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 27 Oct 2026 23:30:13 +0100 Subject: [PATCH] workflow: svcauth, tenantregistryclient aus common v0.1.0 Das Pflichttest-Gate von workflow verweist nicht mehr auf die geloeschten Pakete (common hat ein eigenes Gate). Co-Authored-By: Claude Sonnet 5.5 --- workflow/cmd/workflow-app/main.go | 2 +- workflow/go.mod | 5 +- workflow/go.sum | 2 + .../internal/backchannel/backchannel_test.go | 1 - .../internal/caseoverview/caseoverview.go | 8 ++-- .../caseoverviewapi/caseoverviewapi_test.go | 2 +- .../internal/eventtrigger/eventtrigger.go | 14 +++--- workflow/internal/moduleadapter/handler.go | 2 +- workflow/internal/pflichttestgate/gate.go | 2 - .../internal/pflichttestgate/gate_test.go | 12 ++--- .../internal/routingengine/routingengine.go | 12 ++--- workflow/internal/routingruleapi/handler.go | 4 +- workflow/internal/routingsim/routingsim.go | 6 +-- workflow/internal/svcauth/svcauth.go | 19 -------- .../tenantregistryclient.go | 47 ------------------- 15 files changed, 36 insertions(+), 102 deletions(-) delete mode 100644 workflow/internal/svcauth/svcauth.go delete mode 100644 workflow/internal/tenantregistryclient/tenantregistryclient.go diff --git a/workflow/cmd/workflow-app/main.go b/workflow/cmd/workflow-app/main.go index 1b637622..b5298ce3 100644 --- a/workflow/cmd/workflow-app/main.go +++ b/workflow/cmd/workflow-app/main.go @@ -16,6 +16,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" + "gitea.perlbach24.de/scripte/nexarch/common/tenantregistryclient" "gitea.perlbach24.de/scripte/nexarch/workflow/internal/approval" "gitea.perlbach24.de/scripte/nexarch/workflow/internal/approvalapi" "gitea.perlbach24.de/scripte/nexarch/workflow/internal/backchannel" @@ -33,7 +34,6 @@ import ( "gitea.perlbach24.de/scripte/nexarch/workflow/internal/routingruleapi" "gitea.perlbach24.de/scripte/nexarch/workflow/internal/routingsuggestclient" "gitea.perlbach24.de/scripte/nexarch/workflow/internal/task" - "gitea.perlbach24.de/scripte/nexarch/workflow/internal/tenantregistryclient" ) func requireEnv(name string) string { diff --git a/workflow/go.mod b/workflow/go.mod index 60e3336a..8ec87be2 100644 --- a/workflow/go.mod +++ b/workflow/go.mod @@ -2,7 +2,10 @@ module gitea.perlbach24.de/scripte/nexarch/workflow go 1.25.0 -require github.com/jackc/pgx/v5 v5.9.2 +require ( + gitea.perlbach24.de/scripte/nexarch/common v0.1.0 + github.com/jackc/pgx/v5 v5.9.2 +) require ( github.com/jackc/pgpassfile v1.0.0 // indirect diff --git a/workflow/go.sum b/workflow/go.sum index f5b2410e..a5cc3c17 100644 --- a/workflow/go.sum +++ b/workflow/go.sum @@ -1,3 +1,5 @@ +gitea.perlbach24.de/scripte/nexarch/common v0.1.0 h1:biNzFr2LOMZC7b1leY3smQtrMmSMp6IW80OvR4LSjLY= +gitea.perlbach24.de/scripte/nexarch/common v0.1.0/go.mod h1:CiEImG++QMt1xZqSMeDJhPiB7sfWTLZOwjS6OY/Iguc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= diff --git a/workflow/internal/backchannel/backchannel_test.go b/workflow/internal/backchannel/backchannel_test.go index ed4cf81d..9b7699e4 100644 --- a/workflow/internal/backchannel/backchannel_test.go +++ b/workflow/internal/backchannel/backchannel_test.go @@ -302,4 +302,3 @@ func TestForObject_RegistryTransportError_FailsClosed(t *testing.T) { t.Fatalf("erwartet ErrForbidden bei registry-transportfehler (fail-closed), bekommen %v", err) } } - diff --git a/workflow/internal/caseoverview/caseoverview.go b/workflow/internal/caseoverview/caseoverview.go index a88e43a0..c5e2db49 100644 --- a/workflow/internal/caseoverview/caseoverview.go +++ b/workflow/internal/caseoverview/caseoverview.go @@ -35,10 +35,10 @@ type Detail struct { type KanbanColumn string const ( - ColumnOpen KanbanColumn = "open" - ColumnThisWeek KanbanColumn = "this_week" - ColumnOverdue KanbanColumn = "overdue" - ColumnDone KanbanColumn = "done" + ColumnOpen KanbanColumn = "open" + ColumnThisWeek KanbanColumn = "this_week" + ColumnOverdue KanbanColumn = "overdue" + ColumnDone KanbanColumn = "done" ) // KanbanItem ist eine Wiedervorlage mitsamt der Spalte, in der sie gerade diff --git a/workflow/internal/caseoverviewapi/caseoverviewapi_test.go b/workflow/internal/caseoverviewapi/caseoverviewapi_test.go index 94b6c57d..8b4189f2 100644 --- a/workflow/internal/caseoverviewapi/caseoverviewapi_test.go +++ b/workflow/internal/caseoverviewapi/caseoverviewapi_test.go @@ -5,8 +5,8 @@ import ( "net/http" "net/http/httptest" "os" - "strings" "path/filepath" + "strings" "testing" "time" diff --git a/workflow/internal/eventtrigger/eventtrigger.go b/workflow/internal/eventtrigger/eventtrigger.go index 89c14471..ba35b5f7 100644 --- a/workflow/internal/eventtrigger/eventtrigger.go +++ b/workflow/internal/eventtrigger/eventtrigger.go @@ -174,13 +174,13 @@ func (d *Dispatcher) Dispatch(ctx context.Context) (int, error) { // dasselbe Ereignis reserviert nicht erneut und legt daher auch // keine zweite Aufgabe an (Akzeptanzkriterium 2). // 2. Aufgabe/Genehmigung wird angelegt. -// 3a. Erfolg: die Reservierung wird mit der erzeugten Objekt-ID -// bestaetigt und module_events als verarbeitet markiert. -// 3b. Fehlschlag: die Reservierung wird wieder geloescht, damit ein -// spaeterer Dispatch-Lauf es erneut versuchen kann -- das -// verbleibende Restrisiko ist ein Absturz exakt zwischen 2 und 3a, -// das Ereignis bliebe dann dauerhaft reserviert ohne erzeugtes -// Objekt (dokumentiert in ENG-09-PRUEFPROTOKOLL.md). +// 3a. Erfolg: die Reservierung wird mit der erzeugten Objekt-ID +// bestaetigt und module_events als verarbeitet markiert. +// 3b. Fehlschlag: die Reservierung wird wieder geloescht, damit ein +// spaeterer Dispatch-Lauf es erneut versuchen kann -- das +// verbleibende Restrisiko ist ein Absturz exakt zwischen 2 und 3a, +// das Ereignis bliebe dann dauerhaft reserviert ohne erzeugtes +// Objekt (dokumentiert in ENG-09-PRUEFPROTOKOLL.md). func (d *Dispatcher) dispatchOne(ctx context.Context, e pendingEvent) (bool, error) { rule, ok, err := d.rules.ruleFor(ctx, d.pool, e.ModuleName, e.ObjectType, e.Trigger) if err != nil { diff --git a/workflow/internal/moduleadapter/handler.go b/workflow/internal/moduleadapter/handler.go index b8e043d3..22123c87 100644 --- a/workflow/internal/moduleadapter/handler.go +++ b/workflow/internal/moduleadapter/handler.go @@ -10,7 +10,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "gitea.perlbach24.de/scripte/nexarch/workflow/internal/svcauth" + "gitea.perlbach24.de/scripte/nexarch/common/svcauth" ) // TenantVerifier prueft einen vom aufrufenden Modul mitgelieferten diff --git a/workflow/internal/pflichttestgate/gate.go b/workflow/internal/pflichttestgate/gate.go index f6173167..0e95a2d0 100644 --- a/workflow/internal/pflichttestgate/gate.go +++ b/workflow/internal/pflichttestgate/gate.go @@ -17,9 +17,7 @@ import ( // sensitivePathPatterns beschreibt die Bereiche aus // workflow/docs/TESTSTRATEGIE.md Abschnitt 4. var sensitivePathPatterns = []*regexp.Regexp{ - regexp.MustCompile(`(^|/)workflow/internal/svcauth/`), regexp.MustCompile(`(^|/)workflow/internal/moduleadapter/`), - regexp.MustCompile(`(^|/)workflow/internal/tenantregistryclient/`), regexp.MustCompile(`(^|/)workflow/internal/backchannel/`), regexp.MustCompile(`(^|/)workflow/internal/backchannelapi/`), regexp.MustCompile(`(^|/)workflow/internal/dualcheck/`), diff --git a/workflow/internal/pflichttestgate/gate_test.go b/workflow/internal/pflichttestgate/gate_test.go index 215a5a0a..a0d0aa81 100644 --- a/workflow/internal/pflichttestgate/gate_test.go +++ b/workflow/internal/pflichttestgate/gate_test.go @@ -1,24 +1,24 @@ // Negativtest des Gates selbst (QA-01 Pruefung 1): ein Diff mit -// geaenderter workflow/internal/svcauth/svcauth.go ohne begleitende +// geaenderter workflow/internal/moduleadapter/moduleadapter.go ohne begleitende // Testdatei muss als Verstoss erkannt werden. package pflichttestgate import "testing" func TestCheckDiff_FlagsSensitiveChangeWithoutTest(t *testing.T) { - violations := CheckDiff([]string{"workflow/internal/svcauth/svcauth.go"}) + violations := CheckDiff([]string{"workflow/internal/moduleadapter/moduleadapter.go"}) if len(violations) != 1 { t.Fatalf("erwartet genau 1 verstoss, habe %d: %+v", len(violations), violations) } - if violations[0].Package != "workflow/internal/svcauth" { + if violations[0].Package != "workflow/internal/moduleadapter" { t.Fatalf("falsches package gemeldet: %+v", violations[0]) } } func TestCheckDiff_PassesWhenTestFileAccompanies(t *testing.T) { violations := CheckDiff([]string{ - "workflow/internal/svcauth/svcauth.go", - "workflow/internal/svcauth/svcauth_test.go", + "workflow/internal/moduleadapter/moduleadapter.go", + "workflow/internal/moduleadapter/moduleadapter_test.go", }) if len(violations) != 0 { t.Fatalf("erwartet keine verstoesse, habe: %+v", violations) @@ -34,9 +34,7 @@ func TestCheckDiff_IgnoresNonSensitivePaths(t *testing.T) { func TestCheckDiff_CoversAllSensitivePackages(t *testing.T) { files := []string{ - "workflow/internal/svcauth/x.go", "workflow/internal/moduleadapter/x.go", - "workflow/internal/tenantregistryclient/x.go", "workflow/internal/backchannel/x.go", "workflow/internal/backchannelapi/x.go", "workflow/internal/dualcheck/x.go", diff --git a/workflow/internal/routingengine/routingengine.go b/workflow/internal/routingengine/routingengine.go index bdc8e772..37eda845 100644 --- a/workflow/internal/routingengine/routingengine.go +++ b/workflow/internal/routingengine/routingengine.go @@ -19,12 +19,12 @@ import ( // Decision ist das Ergebnis einer Ausfuehrung: entweder eine passende Regel // mit ihrer Aktion, oder keine Regel (Klaerungskorb). type Decision struct { - Matched bool - RuleID string - RuleName string - Action routingrule.Action - InBasket bool - BasketID string + Matched bool + RuleID string + RuleName string + Action routingrule.Action + InBasket bool + BasketID string } type Engine struct { diff --git a/workflow/internal/routingruleapi/handler.go b/workflow/internal/routingruleapi/handler.go index ad110b0c..7ed896e4 100644 --- a/workflow/internal/routingruleapi/handler.go +++ b/workflow/internal/routingruleapi/handler.go @@ -64,8 +64,8 @@ func (s *Server) handleList(w http.ResponseWriter, r *http.Request, _ string) { } type ruleInput struct { - Name string `json:"name"` - Priority int `json:"priority"` + Name string `json:"name"` + Priority int `json:"priority"` Conditions []routingrule.Condition `json:"conditions"` Actions []routingrule.Action `json:"actions"` } diff --git a/workflow/internal/routingsim/routingsim.go b/workflow/internal/routingsim/routingsim.go index cf55af89..ba7de10e 100644 --- a/workflow/internal/routingsim/routingsim.go +++ b/workflow/internal/routingsim/routingsim.go @@ -13,9 +13,9 @@ import ( // TestCase ist ein Objekt aus dem Testkorpus, optional mit einer erwarteten // Regel-ID (leer = "keine Regel soll greifen"). type TestCase struct { - Label string - Object map[string]any - ExpectedRuleID string + Label string + Object map[string]any + ExpectedRuleID string } // Result ist das Simulationsergebnis fuer einen TestCase: tatsaechliche diff --git a/workflow/internal/svcauth/svcauth.go b/workflow/internal/svcauth/svcauth.go deleted file mode 100644 index 7da2bc8a..00000000 --- a/workflow/internal/svcauth/svcauth.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package svcauth vergleicht Service-Token in konstanter Zeit (Muster aus -// archive/internal/svcauth, Lehre aus RET-14/F-08: ohne diesen Schutz -// beim ersten Entwurf des Adapters einbauen statt nachzuruesten). -package svcauth - -import ( - "crypto/sha256" - "crypto/subtle" -) - -// Equal vergleicht die SHA-256-Werte beider Eingaben in konstanter Zeit. -// Ein leeres erwartetes Token stimmt nie. -func Equal(got, want string) bool { - if want == "" { - return false - } - g, w := sha256.Sum256([]byte(got)), sha256.Sum256([]byte(want)) - return subtle.ConstantTimeCompare(g[:], w[:]) == 1 -} diff --git a/workflow/internal/tenantregistryclient/tenantregistryclient.go b/workflow/internal/tenantregistryclient/tenantregistryclient.go deleted file mode 100644 index d2a803ef..00000000 --- a/workflow/internal/tenantregistryclient/tenantregistryclient.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package tenantregistryclient ist ein schlanker HTTP-Client fuer Core TEN-01 -// (Tenant-Registry); Workflow ist ein eigenes Go-Modul und kann Cores Pakete -// nicht importieren. Gleiches Muster wie dms/internal/tenantregistryclient -// und archive/internal/tenantregistryclient. -package tenantregistryclient - -import ( - "context" - "fmt" - "net/http" - "net/url" - "time" -) - -type Client struct { - BaseURL string - ServiceToken string - HTTPClient *http.Client -} - -func New(baseURL, serviceToken string) *Client { - return &Client{BaseURL: baseURL, ServiceToken: serviceToken, HTTPClient: &http.Client{Timeout: 10 * time.Second}} -} - -// VerifyTenant fragt Core, ob tenantSlug als Tenant gefuehrt wird. Transport- -// und Serverfehler kommen als Fehler zurueck, nie als "gueltig": der Aufrufer -// muss fail-closed reagieren. -func (c *Client) VerifyTenant(ctx context.Context, tenantSlug string) (bool, error) { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.BaseURL+"/tenants/"+url.PathEscape(tenantSlug), nil) - if err != nil { - return false, fmt.Errorf("tenantregistryclient: request bauen: %w", err) - } - req.Header.Set("X-Service-Token", c.ServiceToken) - resp, err := c.HTTPClient.Do(req) - if err != nil { - return false, fmt.Errorf("tenantregistryclient: aufruf fehlgeschlagen: %w", err) - } - defer func() { _ = resp.Body.Close() }() - switch resp.StatusCode { - case http.StatusOK: - return true, nil - case http.StatusNotFound: - return false, nil - default: - return false, fmt.Errorf("tenantregistryclient: unerwarteter status %d", resp.StatusCode) - } -} -- 2.47.3