Feat/asset source settings domain#56
Merged
Merged
Conversation
Lays the foundation for per-tenant asset source priority: domain
types, typed settings field, structural validation, service + HTTP
surface for GET/PUT, and audit action. No behavior change on the
ingest hot path — Phase 1b wires in the priority gate that actually
enforces these settings.
Backward compatibility: a zero-value AssetSourceSettings (empty
Priority + empty TrustLevels) preserves today's last-write-wins
merge exactly. Feature only kicks in when an admin populates either
field through PUT /api/v1/tenants/{id}/settings/asset-source.
- pkg/domain/tenant/trust_level.go — Primary/High/Medium/Low enum,
Rank() + Outranks() for ordering, DefaultTrustLevel = Medium so
existing sources stay neutral on upgrade.
- pkg/domain/tenant/settings.go — new AssetSourceSettings struct
with Priority []shared.ID, TrustLevels map, TrackFieldAttribution
bool, SchemaVersion guard. Validate() rejects duplicate UUIDs,
non-UUID keys, unknown levels. Hooked into Settings.Validate().
- pkg/domain/tenant — Tenant.UpdateAssetSourceSettings mirrors the
pattern used by UpdateRiskScoringSettings.
- pkg/domain/audit — new ActionTenantAssetSourceUpdated constant.
- internal/app/tenant/service.go — TenantService.Update/Get
AssetSourceSettings. Structural validation only for now; existence
check (UUIDs belong to tenant's data_sources) moves into Phase 1b
where the gate naturally joins with that table.
- internal/infra/http/handler/tenant_handler.go — GET + PUT handlers
following the RiskScoring handler shape.
- internal/infra/http/routes/tenant.go — two routes behind
RequireTeamAdmin.
- migrations/000164_asset_source_priority.{up,down}.sql — partial
index on asset_sources(asset_id) WHERE is_primary = true. No data
rewrite. Down migration drops only the index.
- 13 test cases covering: trust-level rank/validate, settings
round-trip through JSON, duplicate/empty/unknown validation,
Tenant update persistence, regression guard that
Settings.Validate() propagates AssetSource errors.
RFC-003 references:
- docs/architecture/asset-source-priority.md (design, on branch
docs/rfc-003-asset-source-priority)
- docs/architecture/asset-source-priority-impl-plan.md (same branch)
Multi-angle review of RFC-003 Phase 1a (commit 4c5ebdc) surfaced six concrete issues across security, testing, and compliance. This commit closes all of them without changing the externally-visible domain shape — the feature remains backward compatible. Security + hardening - Sanitize Validate() error messages: no more echoing user-supplied UUIDs or typo-prone trust-level values back to the caller. The caller already knows what they submitted; not echoing removes a probe-style differentiation channel. - Add MaxAssetSourcePriorityLen (500) + MaxAssetSourceTrustLevels (500) bounds as DoS guards. Oversized payloads return ErrValidation before any storage or dedup work. - Strict JSON decoding on PUT handler — DisallowUnknownFields catches typos (trust_level singular, priorities) that would otherwise silently no-op and confuse admins. Audit / compliance - Replace count-only audit metadata with a before/after diff: priority_before, priority_after, trust_levels_before, trust_levels_after, track_field_attribution_before/after. Sufficient for SOC2/ISO27001 admin-setting change records. Testing - Backward-compat test proves SettingsFromMap gracefully handles legacy JSON missing the "asset_source" key — tenants upgrading from pre-RFC-003 must not panic or auto-enable the feature. - Oversize-input validation coverage (Priority + TrustLevels at limit+1, and exactly-at-limit boundary case). - Security test containsUUIDLike confirms no Validate() error message leaks the submitted UUID shape. - 10 new HTTP handler tests (tests/unit/settings_handler_asset_source_test.go): GET default-disabled, GET missing-context=400, PUT happy path, PUT round-trip-through-GET, PUT unknown-fields=400, PUT duplicate=400, PUT oversize=400, PUT missing-context=400, PUT invalid-json=400, PUT empty-body clears (documented rollback path). No functional change to ingest — Phase 1b is still where the priority gate activates. Backward-compat guarantee intact.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.