diff --git a/enterprise-tooling/enterprise_tooling_api_contract.json b/enterprise-tooling/enterprise_tooling_api_contract.json new file mode 100644 index 00000000..1763e2d3 --- /dev/null +++ b/enterprise-tooling/enterprise_tooling_api_contract.json @@ -0,0 +1,38 @@ +{ + "module": "enterprise-tooling", + "issue": 19, + "version": "v0.1", + "endpoints": [ + { + "method": "GET", + "path": "/api/enterprise/orgs/{org_id}/dashboard", + "summary": "Organization admin dashboard aggregates" + }, + { + "method": "GET", + "path": "/api/enterprise/orgs/{org_id}/audit-logs", + "summary": "Filterable audit log list", + "query": ["from", "to", "severity", "actor", "action"] + }, + { + "method": "POST", + "path": "/api/enterprise/orgs/{org_id}/policies", + "summary": "Create versioned tenant policy" + }, + { + "method": "POST", + "path": "/api/enterprise/orgs/{org_id}/webhooks", + "summary": "Register enterprise webhook endpoint" + }, + { + "method": "GET", + "path": "/api/enterprise/orgs/{org_id}/webhooks/deliveries", + "summary": "Delivery attempts and retry state" + }, + { + "method": "GET", + "path": "/api/enterprise/orgs/{org_id}/usage", + "summary": "Daily usage snapshots" + } + ] +} diff --git a/enterprise-tooling/enterprise_tooling_schema.sql b/enterprise-tooling/enterprise_tooling_schema.sql new file mode 100644 index 00000000..f0336c2f --- /dev/null +++ b/enterprise-tooling/enterprise_tooling_schema.sql @@ -0,0 +1,79 @@ +-- Enterprise Tooling schema (Issue #19) + +create table if not exists enterprise_org ( + id uuid primary key, + org_slug text not null unique, + org_name text not null, + status text not null default 'active', + created_at timestamptz not null default now() +); + +create table if not exists enterprise_admin_user ( + id uuid primary key, + org_id uuid not null references enterprise_org(id), + email text not null, + role text not null, + created_at timestamptz not null default now(), + unique (org_id, email) +); + +create table if not exists enterprise_policy ( + id uuid primary key, + org_id uuid not null references enterprise_org(id), + policy_key text not null, + policy_version integer not null, + policy_payload jsonb not null, + effective_at timestamptz not null default now(), + created_by text not null, + created_at timestamptz not null default now(), + unique (org_id, policy_key, policy_version) +); + +create table if not exists enterprise_audit_log ( + id uuid primary key, + org_id uuid not null references enterprise_org(id), + actor text not null, + action text not null, + target_type text not null, + target_id text not null, + severity text not null default 'info', + metadata jsonb not null default '{}'::jsonb, + created_at timestamptz not null default now() +); + +create index if not exists idx_enterprise_audit_log_org_time + on enterprise_audit_log(org_id, created_at desc); + +create table if not exists enterprise_webhook_endpoint ( + id uuid primary key, + org_id uuid not null references enterprise_org(id), + endpoint_url text not null, + signing_key_ref text not null, + enabled boolean not null default true, + created_at timestamptz not null default now() +); + +create table if not exists enterprise_webhook_delivery ( + id uuid primary key, + endpoint_id uuid not null references enterprise_webhook_endpoint(id), + event_type text not null, + event_id text not null, + attempt integer not null default 1, + status text not null, + response_code integer, + response_excerpt text, + next_retry_at timestamptz, + created_at timestamptz not null default now(), + unique (endpoint_id, event_id, attempt) +); + +create table if not exists enterprise_usage_snapshot ( + org_id uuid not null references enterprise_org(id), + snapshot_date date not null, + active_users integer not null default 0, + projects_count integer not null default 0, + datasets_count integer not null default 0, + api_calls integer not null default 0, + storage_gb numeric(10,2) not null default 0, + primary key (org_id, snapshot_date) +); diff --git a/enterprise-tooling/implementation_plan.md b/enterprise-tooling/implementation_plan.md new file mode 100644 index 00000000..d223fc25 --- /dev/null +++ b/enterprise-tooling/implementation_plan.md @@ -0,0 +1,25 @@ +# Implementation Plan (Issue #19) + +## Phase 1 + +- Apply enterprise schema and policy versioning primitives. +- Build audit-log write/read path and org dashboard aggregate endpoint. +- Seed base tenant policy keys and defaults. + +## Phase 2 + +- Implement webhook endpoint registration + signed delivery worker. +- Implement retry strategy with dead-letter state. +- Add usage snapshot generation and trend API. + +## Phase 3 + +- Add enterprise admin UI for policy rollout and audit filtering. +- Add exportable compliance reports. +- Add rate-limited alerting for failed webhook deliveries. + +## Success Criteria + +- Tenant policy updates are versioned and auditable. +- All privileged actions emit immutable audit records. +- Webhook delivery outcomes are observable and replayable. diff --git a/enterprise-tooling/readme.md b/enterprise-tooling/readme.md new file mode 100644 index 00000000..b2e28990 --- /dev/null +++ b/enterprise-tooling/readme.md @@ -0,0 +1,25 @@ +# Enterprise Tooling (Issue #19) + +This module establishes a concrete foundation for institution-grade governance, +analytics, and integration controls. + +## Deliverables in this PR + +- Enterprise data model (`enterprise_tooling_schema.sql`) +- Admin API contract (`enterprise_tooling_api_contract.json`) +- Rollout sequence (`implementation_plan.md`) + +## Scope + +- Org-level admin dashboard primitives +- Compliance and audit log model +- Integration webhook registry and event delivery records +- Usage analytics snapshot tables +- Tenant policy and access control baselines + +## Principles + +- Auditability first (immutable operational logs) +- Safe multi-tenant boundaries +- Versioned policy changes +- Replayable webhook delivery state