feat(control-plane): harden host-scoped reconcile and acceptance evidence

- add batch-scoped reconcile_runs persistence and queries
- route batch detail and reconcile writes through batch_id/host_id
- refresh production boards with host-scope acceptance artifacts
- include latest real-host acceptance evidence for self_service and subscription
This commit is contained in:
phamnazage-jpg
2026-05-18 22:22:22 +08:00
parent 71cbaf5fa6
commit 85d495dd16
332 changed files with 5561 additions and 422 deletions

View File

@@ -8,27 +8,27 @@ import (
)
func (c *Client) ProbeCapabilities(ctx context.Context) (HostCapabilities, error) {
groups, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/groups", map[string]any{})
groups, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/groups", nil)
if err != nil {
return HostCapabilities{}, err
}
channels, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/channels", map[string]any{})
channels, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/channels", nil)
if err != nil {
return HostCapabilities{}, err
}
plans, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/payment/plans", map[string]any{})
plans, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/payment/plans", nil)
if err != nil {
return HostCapabilities{}, err
}
accounts, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/accounts", map[string]any{})
accounts, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/accounts", nil)
if err != nil {
return HostCapabilities{}, err
}
accountTest, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/accounts/__probe__/test", map[string]any{})
accountTest, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/accounts/__probe__/test", nil)
if err != nil {
return HostCapabilities{}, err
}
@@ -38,7 +38,7 @@ func (c *Client) ProbeCapabilities(ctx context.Context) (HostCapabilities, error
return HostCapabilities{}, err
}
subscriptions, err := c.probeEndpoint(ctx, http.MethodPost, "/api/v1/admin/subscriptions/assign", map[string]any{})
subscriptions, err := c.probeEndpoint(ctx, http.MethodGet, "/api/v1/admin/subscriptions/assign", nil)
if err != nil {
return HostCapabilities{}, err
}
@@ -55,7 +55,7 @@ func (c *Client) ProbeCapabilities(ctx context.Context) (HostCapabilities, error
}
func (c *Client) probeEndpoint(ctx context.Context, method, path string, requestBody any) (bool, error) {
statusCode, headers, body, err := c.perform(ctx, method, path, requestBody)
statusCode, _, body, err := c.perform(ctx, method, path, requestBody)
if err != nil {
return false, err
}
@@ -66,7 +66,7 @@ func (c *Client) probeEndpoint(ctx context.Context, method, path string, request
case statusCode == http.StatusUnauthorized || statusCode == http.StatusForbidden:
return false, newHTTPError(method, path, statusCode, body)
case statusCode == http.StatusNotFound || statusCode == http.StatusMethodNotAllowed:
return looksLikeExistingEndpoint(headers, body), nil
return false, nil
case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError:
return true, nil
default: