@bugmole/cli 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bugmole.env.example +20 -0
- package/LICENSE +7 -0
- package/README.md +293 -0
- package/TESTING.md +117 -0
- package/bugmole.config.yaml +39 -0
- package/package.json +85 -0
- package/scripts/billing/paypal-setup.mjs +121 -0
- package/scripts/bugmole-continue.ts +318 -0
- package/scripts/bugmole-init.ts +188 -0
- package/scripts/bugmole.cjs +17 -0
- package/scripts/bugmole.test.ts +344 -0
- package/scripts/bugmole.ts +657 -0
- package/scripts/ensure-maestro.cjs +79 -0
- package/scripts/ios-tunnel-keeper.sh +45 -0
- package/scripts/ios-wda-keeper.sh +66 -0
- package/scripts/sync-plan-catalog.d.mts +3 -0
- package/scripts/sync-plan-catalog.mjs +16 -0
- package/scripts/ui-parity-diff.py +65 -0
- package/scripts/ui-parity-requirements.txt +1 -0
- package/scripts/verify-manage-to-plans.mts +194 -0
- package/spec/app-ui-audit.schema.json +176 -0
- package/spec/blockers.yaml +79 -0
- package/spec/bugs.index.json +42 -0
- package/spec/design-dna.schema.json +38 -0
- package/spec/domain_rules.yaml +24 -0
- package/spec/flows/flow_manage-to-plans-64c3c61b.yaml +8 -0
- package/spec/flows/flow_screen-to-evidence-6c3ab309.yaml +7 -0
- package/spec/journey_graph.yaml +126 -0
- package/spec/journeys.graph.json +2618 -0
- package/spec/plans/dashboard-smoke.flow.yaml +20 -0
- package/spec/plans/example.flow.yaml +99 -0
- package/spec/plans/flow_api-keys-to-logout-7396cd5d.flow.yaml +33 -0
- package/spec/plans/flow_api-keys-to-screen-157e10a6.flow.yaml +33 -0
- package/spec/plans/flow_manage-to-audits-176c1eb8.flow.yaml +33 -0
- package/spec/plans/flow_manage-to-blockers-633282c8.flow.yaml +112 -0
- package/spec/plans/flow_manage-to-devices-ad57e202.flow.yaml +33 -0
- package/spec/plans/flow_manage-to-logout-86c54656.flow.yaml +33 -0
- package/spec/plans/flow_manage-to-manage-resource-action-6325f99a.flow.yaml +185 -0
- package/spec/plans/flow_manage-to-parity-issues-01fa2579.flow.yaml +34 -0
- package/spec/plans/flow_manage-to-plans-64c3c61b.flow.yaml +123 -0
- package/spec/plans/flow_manage-to-screen-6857f915.flow.yaml +106 -0
- package/spec/plans/flow_manage-to-tasks-c5791c95.flow.yaml +33 -0
- package/spec/plans/flow_profile-to-screen-6045aa3d.flow.yaml +33 -0
- package/spec/plans/flow_register-to-api-auth-login-460a9cc8.flow.yaml +34 -0
- package/spec/plans/flow_screen-to-audits-07666356.flow.yaml +33 -0
- package/spec/plans/flow_screen-to-blockers-091d258b.flow.yaml +33 -0
- package/spec/plans/flow_screen-to-devices-cad72f75.flow.yaml +33 -0
- package/spec/plans/flow_screen-to-evidence-6c3ab309.flow.yaml +126 -0
- package/spec/plans/flow_screen-to-parity-issues-2218e3ad.flow.yaml +34 -0
- package/spec/plans/flow_screen-to-plans-8232a94f.flow.yaml +33 -0
- package/spec/plans/flow_screen-to-tasks-540671d1.flow.yaml +33 -0
- package/spec/plans/login.flow.yaml +22 -0
- package/spec/plans/owner-operations.flow.yaml +20 -0
- package/spec/project_config.yaml +55 -0
- package/spec/roles.yaml +30 -0
- package/spec/schema.md +394 -0
- package/spec/test-case-results.schema.json +62 -0
- package/spec/test-cases.schema.json +85 -0
- package/spec/ui-parity-audit.schema.json +194 -0
- package/spec/ui-reverse-engineering.schema.json +94 -0
- package/src/billing/plan-catalog.test.ts +46 -0
- package/src/billing/plan-catalog.ts +199 -0
- package/src/integrations/aws-sigv4.test.ts +42 -0
- package/src/integrations/aws-sigv4.ts +72 -0
- package/src/integrations/device-farm.ts +155 -0
- package/src/integrations/github-app.test.ts +57 -0
- package/src/integrations/github-app.ts +143 -0
- package/src/integrations/gitlab.ts +81 -0
- package/src/integrations/temp-email.test.ts +123 -0
- package/src/integrations/temp-email.ts +175 -0
- package/src/integrations/testflight-feedback.test.ts +51 -0
- package/src/integrations/testflight-feedback.ts +173 -0
- package/src/integrations/webdriver-client.ts +131 -0
- package/src/mcp/server.test.ts +1220 -0
- package/src/mcp/server.ts +3064 -0
- package/src/mcp/write-test-cases.test.ts +287 -0
- package/src/registry/api-key-client.ts +39 -0
- package/src/registry/control-plane-client.ts +212 -0
- package/src/registry/migrations/0001_registry.sql +47 -0
- package/src/registry/migrations/0002_device_authorizations.sql +23 -0
- package/src/registry/migrations/0003_project_environments.sql +25 -0
- package/src/registry/migrations/0004_device_authorization_email.sql +1 -0
- package/src/registry/migrations/0005_testing_control_plane.sql +55 -0
- package/src/registry/migrations/0006_workspaces.sql +36 -0
- package/src/registry/migrations/0007_project_apps.sql +26 -0
- package/src/registry/migrations/0008_agent_tasks.sql +30 -0
- package/src/registry/migrations/0009_journey_revisions.sql +17 -0
- package/src/registry/migrations/0010_agent_task_journey.sql +2 -0
- package/src/registry/migrations/0011_run_journey_revision.sql +1 -0
- package/src/registry/migrations/0012_canonical_flow_execution.sql +10 -0
- package/src/registry/migrations/0013_device_sessions.sql +22 -0
- package/src/registry/migrations/0014_agent_task_step.sql +1 -0
- package/src/registry/migrations/0015_agent_task_attempts.sql +6 -0
- package/src/registry/migrations/0016_github_issue_tracker.sql +54 -0
- package/src/registry/migrations/0017_run_targets.sql +7 -0
- package/src/registry/migrations/0018_run_fix_from.sql +4 -0
- package/src/registry/migrations/0019_workspace_flags.sql +9 -0
- package/src/registry/migrations/0020_orgs.sql +40 -0
- package/src/registry/migrations/0021_billing_core.sql +58 -0
- package/src/registry/migrations/0022_cloud_runners.sql +19 -0
- package/src/registry/migrations/0023_signup.sql +4 -0
- package/src/registry/migrations/0024_billing.sql +67 -0
- package/src/registry/migrations/0025_notifications.sql +47 -0
- package/src/registry/migrations/0026_repo_bindings.sql +28 -0
- package/src/registry/migrations/0027_feedback.sql +29 -0
- package/src/registry/migrations/0028_devices.sql +48 -0
- package/src/registry/migrations/0029_sso.sql +31 -0
- package/src/registry/migrations/0030_workspace_domains.sql +18 -0
- package/src/registry/migrations/0031_gitlab_and_teams.sql +45 -0
- package/src/registry/migrations/0032_personas.sql +15 -0
- package/src/registry/migrations/0033_bugmole_rename.sql +11 -0
- package/src/registry/task-scheduling.test.ts +100 -0
- package/src/registry/task-scheduling.ts +80 -0
- package/src/registry-worker/ai/platform-model.ts +77 -0
- package/src/registry-worker/ai/routes.test.ts +88 -0
- package/src/registry-worker/ai/routes.ts +90 -0
- package/src/registry-worker/artifacts.test.ts +98 -0
- package/src/registry-worker/artifacts.ts +85 -0
- package/src/registry-worker/billing/billing-core.test.ts +175 -0
- package/src/registry-worker/billing/checkout-routes.ts +209 -0
- package/src/registry-worker/billing/enforcement.ts +69 -0
- package/src/registry-worker/billing/entitlements.ts +108 -0
- package/src/registry-worker/billing/ledger.ts +186 -0
- package/src/registry-worker/billing/paypal/api.ts +259 -0
- package/src/registry-worker/billing/paypal/client.ts +91 -0
- package/src/registry-worker/billing/paypal/provider.ts +143 -0
- package/src/registry-worker/billing/paypal.test.ts +466 -0
- package/src/registry-worker/billing/provider.ts +114 -0
- package/src/registry-worker/billing/routes.ts +66 -0
- package/src/registry-worker/billing/subscriptions.ts +780 -0
- package/src/registry-worker/billing/thresholds.ts +107 -0
- package/src/registry-worker/core.ts +308 -0
- package/src/registry-worker/devices/devices.test.ts +185 -0
- package/src/registry-worker/devices/policy.ts +71 -0
- package/src/registry-worker/devices/routes.ts +453 -0
- package/src/registry-worker/domains/domains.test.ts +210 -0
- package/src/registry-worker/domains/routes.ts +139 -0
- package/src/registry-worker/domains.ts +88 -0
- package/src/registry-worker/email/sender.ts +75 -0
- package/src/registry-worker/env.d.ts +14716 -0
- package/src/registry-worker/features.ts +20 -0
- package/src/registry-worker/feedback/feedback.test.ts +230 -0
- package/src/registry-worker/feedback/format.ts +148 -0
- package/src/registry-worker/feedback/routes.ts +386 -0
- package/src/registry-worker/flags.ts +39 -0
- package/src/registry-worker/github/checks.test.ts +177 -0
- package/src/registry-worker/github/checks.ts +374 -0
- package/src/registry-worker/gitlab/checks.test.ts +141 -0
- package/src/registry-worker/gitlab/checks.ts +349 -0
- package/src/registry-worker/hooks.ts +54 -0
- package/src/registry-worker/index.ts +2077 -0
- package/src/registry-worker/jobs/index.ts +29 -0
- package/src/registry-worker/jobs/retention.ts +68 -0
- package/src/registry-worker/mcp/mcp.test.ts +355 -0
- package/src/registry-worker/mcp/routes.ts +215 -0
- package/src/registry-worker/mcp/token.ts +126 -0
- package/src/registry-worker/mcp/tools.ts +563 -0
- package/src/registry-worker/notifications/alerts.ts +212 -0
- package/src/registry-worker/notifications/notifications.test.ts +298 -0
- package/src/registry-worker/notifications/outbox.ts +83 -0
- package/src/registry-worker/notifications/routes.ts +280 -0
- package/src/registry-worker/notifications/secrets.ts +49 -0
- package/src/registry-worker/notifications/slack.ts +96 -0
- package/src/registry-worker/notifications/teams.ts +46 -0
- package/src/registry-worker/org/audit.ts +116 -0
- package/src/registry-worker/org/routes.test.ts +163 -0
- package/src/registry-worker/org/routes.ts +302 -0
- package/src/registry-worker/personas/personas.test.ts +78 -0
- package/src/registry-worker/personas/routes.ts +100 -0
- package/src/registry-worker/repo-triggers.ts +20 -0
- package/src/registry-worker/routes/index.ts +74 -0
- package/src/registry-worker/run-events.ts +24 -0
- package/src/registry-worker/runner/dispatch.ts +219 -0
- package/src/registry-worker/runner/jobs.ts +43 -0
- package/src/registry-worker/runner/metering.ts +82 -0
- package/src/registry-worker/runner/policy.ts +59 -0
- package/src/registry-worker/runner/routes.ts +171 -0
- package/src/registry-worker/runner/runner.test.ts +358 -0
- package/src/registry-worker/runner/tokens.ts +93 -0
- package/src/registry-worker/runs.test.ts +60 -0
- package/src/registry-worker/signup/policy.ts +57 -0
- package/src/registry-worker/signup/routes.ts +106 -0
- package/src/registry-worker/signup/signup.test.ts +81 -0
- package/src/registry-worker/sso/aegis.ts +141 -0
- package/src/registry-worker/sso/membership.ts +157 -0
- package/src/registry-worker/sso/routes.ts +458 -0
- package/src/registry-worker/sso/sso.test.ts +344 -0
- package/src/registry-worker/testing/d1-shim.ts +180 -0
- package/src/registry-worker/testing/harness.ts +137 -0
- package/src/runner-worker/index.ts +108 -0
- package/src/runtime/ai-analysis.ts +97 -0
- package/src/runtime/ai-exploration.test.ts +32 -0
- package/src/runtime/ai-exploration.ts +69 -0
- package/src/runtime/ai-repair.ts +74 -0
- package/src/runtime/ai-work.test.ts +99 -0
- package/src/runtime/android-screen-record.test.ts +75 -0
- package/src/runtime/android-screen-record.ts +192 -0
- package/src/runtime/app-understanding.test.ts +123 -0
- package/src/runtime/app-understanding.ts +201 -0
- package/src/runtime/appium-driver.test.ts +179 -0
- package/src/runtime/appium-driver.ts +295 -0
- package/src/runtime/blocker-resolution.test.ts +113 -0
- package/src/runtime/blocker-resolution.ts +111 -0
- package/src/runtime/browser-matrix.integration.test.ts +212 -0
- package/src/runtime/browser-matrix.test.ts +143 -0
- package/src/runtime/browser-matrix.ts +200 -0
- package/src/runtime/canonical-flow.test.ts +52 -0
- package/src/runtime/config-validate.ts +185 -0
- package/src/runtime/continuous-execution.ts +291 -0
- package/src/runtime/cursor-applescript.ts +573 -0
- package/src/runtime/cursor-cli-driver.test.ts +78 -0
- package/src/runtime/cursor-cli-driver.ts +156 -0
- package/src/runtime/cursor-driver-example.ts +117 -0
- package/src/runtime/cursor-driver-index.ts +65 -0
- package/src/runtime/cursor-driver-init.ts +277 -0
- package/src/runtime/cursor-driver-run.test.ts +15 -0
- package/src/runtime/cursor-driver-run.ts +323 -0
- package/src/runtime/cursor-driver.ts +332 -0
- package/src/runtime/cursor-llm-example.ts +90 -0
- package/src/runtime/cursor-llm.ts +206 -0
- package/src/runtime/cursor-mcp-monitor.ts +386 -0
- package/src/runtime/device-clouds/browserstack.ts +73 -0
- package/src/runtime/device-clouds/device-farm.ts +52 -0
- package/src/runtime/device-clouds/index.ts +92 -0
- package/src/runtime/device-clouds/kobiton.ts +70 -0
- package/src/runtime/device-clouds/targets.ts +44 -0
- package/src/runtime/device-clouds/types.ts +62 -0
- package/src/runtime/diff-proposal.ts +84 -0
- package/src/runtime/discovery-task.test.ts +29 -0
- package/src/runtime/discovery-task.ts +284 -0
- package/src/runtime/driver-recovery.ts +69 -0
- package/src/runtime/driver.ts +79 -0
- package/src/runtime/environment.test.ts +104 -0
- package/src/runtime/environment.ts +137 -0
- package/src/runtime/executor.test.ts +509 -0
- package/src/runtime/executor.ts +921 -0
- package/src/runtime/explorer.test.ts +101 -0
- package/src/runtime/explorer.ts +1013 -0
- package/src/runtime/failure-analysis.test.ts +111 -0
- package/src/runtime/failure-analysis.ts +272 -0
- package/src/runtime/fixtures/fake-maestro.sh +36 -0
- package/src/runtime/flow-language.test.ts +268 -0
- package/src/runtime/flow-language.ts +414 -0
- package/src/runtime/init-wizard.ts +354 -0
- package/src/runtime/ios-screen-record.test.ts +68 -0
- package/src/runtime/ios-screen-record.ts +155 -0
- package/src/runtime/journey-editor.ts +452 -0
- package/src/runtime/journey-evidence.test.ts +161 -0
- package/src/runtime/journey-evidence.ts +180 -0
- package/src/runtime/journey-graph.test.ts +257 -0
- package/src/runtime/journey-graph.ts +170 -0
- package/src/runtime/legacy-names.ts +32 -0
- package/src/runtime/llm-example.ts +105 -0
- package/src/runtime/llm.ts +527 -0
- package/src/runtime/local-browser.test.ts +45 -0
- package/src/runtime/local-browser.ts +48 -0
- package/src/runtime/local-registry-stub.test.ts +325 -0
- package/src/runtime/local-registry-stub.ts +803 -0
- package/src/runtime/maestro-driver.test.ts +84 -0
- package/src/runtime/maestro-driver.ts +209 -0
- package/src/runtime/mole-voice.ts +21 -0
- package/src/runtime/nav-crawl.test.ts +100 -0
- package/src/runtime/nav-crawl.ts +153 -0
- package/src/runtime/pipeline.test.ts +405 -0
- package/src/runtime/pipeline.ts +833 -0
- package/src/runtime/planner.test.ts +37 -0
- package/src/runtime/planner.ts +274 -0
- package/src/runtime/platform-ai.ts +76 -0
- package/src/runtime/playwright-driver.test.ts +93 -0
- package/src/runtime/playwright-driver.ts +620 -0
- package/src/runtime/project-spec.ts +140 -0
- package/src/runtime/record-run-verdicts.ts +68 -0
- package/src/runtime/reporter.test.ts +56 -0
- package/src/runtime/reporter.ts +158 -0
- package/src/runtime/reset.test.ts +44 -0
- package/src/runtime/reset.ts +61 -0
- package/src/runtime/reviewer.test.ts +73 -0
- package/src/runtime/reviewer.ts +158 -0
- package/src/runtime/run-job.ts +136 -0
- package/src/runtime/run-once.test.ts +207 -0
- package/src/runtime/run-once.ts +168 -0
- package/src/runtime/run.ts +132 -0
- package/src/runtime/screen-recording.ts +34 -0
- package/src/runtime/serve-gateway.test.ts +74 -0
- package/src/runtime/serve-gateway.ts +164 -0
- package/src/runtime/serve-worker.test.ts +23 -0
- package/src/runtime/serve-worker.ts +278 -0
- package/src/runtime/site-discovery.test.ts +168 -0
- package/src/runtime/site-discovery.ts +308 -0
- package/src/runtime/target-runner.ts +144 -0
- package/src/runtime/test-case-verdicts.test.ts +94 -0
- package/src/runtime/test-case-verdicts.ts +120 -0
- package/src/runtime/ui-reverse-engineering/coordinator.test.ts +59 -0
- package/src/runtime/ui-reverse-engineering/coordinator.ts +391 -0
- package/src/runtime/ui-reverse-engineering/types.ts +197 -0
- package/src/runtime/web-suite.test.ts +97 -0
- package/src/runtime/web-suite.ts +176 -0
- package/src/storage/create-object-store.ts +144 -0
- package/src/storage/keys.ts +34 -0
- package/src/storage/local-artifact-server.test.ts +314 -0
- package/src/storage/local-artifact-server.ts +357 -0
- package/src/storage/object-store.test.ts +28 -0
- package/src/storage/object-store.ts +101 -0
- package/src/storage/registry-object-store.ts +88 -0
- package/src/storage/remote-object-store.ts +104 -0
- package/src/storage/storage-directory.test.ts +43 -0
- package/src/storage/storage-directory.ts +24 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
name TEXT NOT NULL,
|
|
4
|
+
created_by TEXT NOT NULL REFERENCES aegis_users(id),
|
|
5
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS workspace_memberships (
|
|
9
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
10
|
+
aegis_id TEXT NOT NULL REFERENCES aegis_users(id) ON DELETE CASCADE,
|
|
11
|
+
role TEXT NOT NULL,
|
|
12
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
13
|
+
PRIMARY KEY (workspace_id, aegis_id)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
ALTER TABLE projects ADD COLUMN workspace_id TEXT REFERENCES workspaces(id);
|
|
17
|
+
|
|
18
|
+
INSERT OR IGNORE INTO workspaces (id, name, created_by)
|
|
19
|
+
SELECT tenant_id, tenant_id, MIN(m.aegis_id)
|
|
20
|
+
FROM projects p
|
|
21
|
+
JOIN project_memberships m ON m.project_id = p.id
|
|
22
|
+
GROUP BY tenant_id;
|
|
23
|
+
|
|
24
|
+
INSERT OR IGNORE INTO workspace_memberships (workspace_id, aegis_id, role, status)
|
|
25
|
+
SELECT p.tenant_id, m.aegis_id, 'owner', 'active'
|
|
26
|
+
FROM projects p
|
|
27
|
+
JOIN project_memberships m ON m.project_id = p.id
|
|
28
|
+
WHERE m.role = 'owner';
|
|
29
|
+
|
|
30
|
+
UPDATE projects SET workspace_id = tenant_id WHERE workspace_id IS NULL;
|
|
31
|
+
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_memberships_aegis
|
|
33
|
+
ON workspace_memberships(aegis_id, status);
|
|
34
|
+
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_projects_workspace
|
|
36
|
+
ON projects(workspace_id, created_at DESC);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS project_apps (
|
|
2
|
+
id TEXT NOT NULL,
|
|
3
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
4
|
+
name TEXT NOT NULL,
|
|
5
|
+
type TEXT NOT NULL DEFAULT 'web',
|
|
6
|
+
location TEXT,
|
|
7
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
is_default INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
PRIMARY KEY (project_id, id)
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
ALTER TABLE project_environments ADD COLUMN app_id TEXT;
|
|
13
|
+
|
|
14
|
+
INSERT OR IGNORE INTO project_apps (id, project_id, name, type, is_default)
|
|
15
|
+
SELECT 'default', id, name, 'web', 1
|
|
16
|
+
FROM projects;
|
|
17
|
+
|
|
18
|
+
UPDATE project_environments
|
|
19
|
+
SET app_id = 'default'
|
|
20
|
+
WHERE app_id IS NULL;
|
|
21
|
+
|
|
22
|
+
CREATE INDEX IF NOT EXISTS idx_project_apps_project
|
|
23
|
+
ON project_apps(project_id, created_at);
|
|
24
|
+
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_project_environments_app
|
|
26
|
+
ON project_environments(project_id, app_id, status);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS agent_tasks (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
4
|
+
tenant_id TEXT NOT NULL,
|
|
5
|
+
title TEXT NOT NULL,
|
|
6
|
+
description TEXT NOT NULL,
|
|
7
|
+
task_type TEXT NOT NULL DEFAULT 'code',
|
|
8
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
status TEXT NOT NULL DEFAULT 'queued',
|
|
10
|
+
requested_by TEXT NOT NULL,
|
|
11
|
+
worker_id TEXT,
|
|
12
|
+
lease_expires_at TEXT,
|
|
13
|
+
heartbeat_at TEXT,
|
|
14
|
+
progress_message TEXT,
|
|
15
|
+
continuation_json TEXT,
|
|
16
|
+
baseline_match_score REAL,
|
|
17
|
+
parity_match_score REAL,
|
|
18
|
+
parity_audit_id TEXT,
|
|
19
|
+
completion_summary TEXT,
|
|
20
|
+
changed_files_json TEXT,
|
|
21
|
+
error_message TEXT,
|
|
22
|
+
idempotency_key TEXT NOT NULL,
|
|
23
|
+
requested_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
24
|
+
started_at TEXT,
|
|
25
|
+
completed_at TEXT,
|
|
26
|
+
UNIQUE(project_id, idempotency_key)
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_agent_tasks_project_status
|
|
30
|
+
ON agent_tasks(project_id, status, priority DESC, requested_at ASC);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS journey_revisions (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
4
|
+
tenant_id TEXT NOT NULL,
|
|
5
|
+
journey_id TEXT NOT NULL,
|
|
6
|
+
revision INTEGER NOT NULL,
|
|
7
|
+
object_key TEXT NOT NULL,
|
|
8
|
+
app_id TEXT,
|
|
9
|
+
environment_id TEXT,
|
|
10
|
+
status TEXT NOT NULL DEFAULT 'draft',
|
|
11
|
+
created_by TEXT NOT NULL,
|
|
12
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
UNIQUE(project_id, journey_id, revision)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_journey_revisions_project
|
|
17
|
+
ON journey_revisions(project_id, journey_id, revision DESC);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE runs ADD COLUMN journey_revision INTEGER;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ALTER TABLE journey_revisions ADD COLUMN source_of_truth TEXT NOT NULL DEFAULT 'canonical_flow';
|
|
2
|
+
ALTER TABLE journey_revisions ADD COLUMN stability TEXT NOT NULL DEFAULT 'discovered';
|
|
3
|
+
ALTER TABLE journey_revisions ADD COLUMN linked_to_graph INTEGER NOT NULL DEFAULT 0;
|
|
4
|
+
ALTER TABLE journey_revisions ADD COLUMN verification_run_id TEXT;
|
|
5
|
+
|
|
6
|
+
ALTER TABLE runs ADD COLUMN driver TEXT NOT NULL DEFAULT 'maestro';
|
|
7
|
+
ALTER TABLE runs ADD COLUMN platform TEXT;
|
|
8
|
+
ALTER TABLE runs ADD COLUMN recovery_attempts INTEGER NOT NULL DEFAULT 0;
|
|
9
|
+
ALTER TABLE runs ADD COLUMN failure_code TEXT;
|
|
10
|
+
ALTER TABLE runs ADD COLUMN artifact_summary_json TEXT;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS device_sessions (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
device_id TEXT NOT NULL,
|
|
4
|
+
provider TEXT NOT NULL,
|
|
5
|
+
device_type TEXT NOT NULL,
|
|
6
|
+
native_session_id TEXT NOT NULL,
|
|
7
|
+
tenant_id TEXT NOT NULL,
|
|
8
|
+
state TEXT NOT NULL,
|
|
9
|
+
started_at TEXT NOT NULL,
|
|
10
|
+
stopped_at TEXT,
|
|
11
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
UNIQUE(provider, native_session_id)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_device_sessions_tenant
|
|
17
|
+
ON device_sessions(tenant_id, started_at DESC);
|
|
18
|
+
|
|
19
|
+
ALTER TABLE agent_tasks ADD COLUMN device_session_id TEXT REFERENCES device_sessions(id);
|
|
20
|
+
|
|
21
|
+
CREATE INDEX IF NOT EXISTS idx_agent_tasks_device_session
|
|
22
|
+
ON agent_tasks(device_session_id);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE agent_tasks ADD COLUMN step_id TEXT;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- Blocked tasks were re-served on every 5s worker poll forever: task
|
|
2
|
+
-- selection accepted `status IN ('queued','blocked')` with no attempt
|
|
3
|
+
-- counter and no backoff, so a task that always fails would be retried
|
|
4
|
+
-- indefinitely. An autonomous pipeline built on that would spin.
|
|
5
|
+
ALTER TABLE agent_tasks ADD COLUMN attempts INTEGER NOT NULL DEFAULT 0;
|
|
6
|
+
ALTER TABLE agent_tasks ADD COLUMN next_attempt_at TEXT;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS github_installations (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
4
|
+
installation_id INTEGER NOT NULL,
|
|
5
|
+
account_login TEXT NOT NULL,
|
|
6
|
+
account_type TEXT NOT NULL,
|
|
7
|
+
repository_selection TEXT NOT NULL,
|
|
8
|
+
repositories_json TEXT NOT NULL DEFAULT '[]',
|
|
9
|
+
connected_by TEXT NOT NULL,
|
|
10
|
+
connected_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
revoked_at TEXT
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
-- Not unique on installation_id alone: the same GitHub App installation can
|
|
15
|
+
-- legitimately be connected to more than one Valkyrie project (e.g. a shared
|
|
16
|
+
-- backend repo backing two projects), so uniqueness is scoped per project.
|
|
17
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_github_installations_project_installation
|
|
18
|
+
ON github_installations(project_id, installation_id);
|
|
19
|
+
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_github_installations_installation
|
|
21
|
+
ON github_installations(installation_id);
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS issue_tracker_links (
|
|
24
|
+
id TEXT PRIMARY KEY,
|
|
25
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
26
|
+
provider TEXT NOT NULL DEFAULT 'github',
|
|
27
|
+
installation_id INTEGER,
|
|
28
|
+
owner TEXT NOT NULL,
|
|
29
|
+
repo TEXT NOT NULL,
|
|
30
|
+
issue_number INTEGER NOT NULL,
|
|
31
|
+
issue_node_id TEXT,
|
|
32
|
+
url TEXT NOT NULL,
|
|
33
|
+
title TEXT NOT NULL,
|
|
34
|
+
state TEXT NOT NULL DEFAULT 'unknown',
|
|
35
|
+
finding_kind TEXT NOT NULL,
|
|
36
|
+
finding_key TEXT NOT NULL,
|
|
37
|
+
created_by TEXT NOT NULL,
|
|
38
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
39
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
40
|
+
last_sync_source TEXT NOT NULL DEFAULT 'create'
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
-- At most one active link per finding per project: prevents a single parity
|
|
44
|
+
-- issue or TestFlight feedback item from pointing at two tracker issues.
|
|
45
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_issue_links_finding
|
|
46
|
+
ON issue_tracker_links(project_id, provider, finding_kind, finding_key);
|
|
47
|
+
|
|
48
|
+
-- Reverse lookup used by the GitHub webhook handler: an `issues` event only
|
|
49
|
+
-- carries owner/repo/issue_number, never our finding_key.
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_issue_links_external
|
|
51
|
+
ON issue_tracker_links(provider, owner, repo, issue_number);
|
|
52
|
+
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_issue_links_project
|
|
54
|
+
ON issue_tracker_links(project_id, updated_at);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- A run fans out across a browser/device matrix and hits the environment it
|
|
2
|
+
-- was requested against. The base URL is snapshotted at request time so the
|
|
3
|
+
-- worker needs no extra lookup and the run records which URL it really hit,
|
|
4
|
+
-- even if the environment is edited later.
|
|
5
|
+
ALTER TABLE runs ADD COLUMN targets_json TEXT;
|
|
6
|
+
ALTER TABLE runs ADD COLUMN environment_base_url TEXT;
|
|
7
|
+
ALTER TABLE runs ADD COLUMN target_results_json TEXT;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Per-workspace opt-in for features that are still rolling out, so a feature
|
|
2
|
+
-- can run for internal workspaces before its global flag is turned on.
|
|
3
|
+
CREATE TABLE IF NOT EXISTS workspace_flags (
|
|
4
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
5
|
+
flag TEXT NOT NULL,
|
|
6
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
7
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
PRIMARY KEY (workspace_id, flag)
|
|
9
|
+
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- Organizations: enforced workspace roles (owner, admin, member, billing),
|
|
2
|
+
-- invitations, and an audit log of who changed what.
|
|
3
|
+
-- Existing memberships keep their 'owner' role; roles are validated in code
|
|
4
|
+
-- because SQLite can't add a CHECK constraint to an existing table.
|
|
5
|
+
ALTER TABLE workspace_memberships ADD COLUMN invited_by TEXT;
|
|
6
|
+
ALTER TABLE workspace_memberships ADD COLUMN created_at TEXT;
|
|
7
|
+
ALTER TABLE projects ADD COLUMN deleted_at TEXT;
|
|
8
|
+
|
|
9
|
+
CREATE TABLE IF NOT EXISTS workspace_invitations (
|
|
10
|
+
id TEXT PRIMARY KEY,
|
|
11
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
12
|
+
email TEXT NOT NULL,
|
|
13
|
+
role TEXT NOT NULL,
|
|
14
|
+
token_hash TEXT NOT NULL UNIQUE,
|
|
15
|
+
invited_by TEXT NOT NULL,
|
|
16
|
+
expires_at TEXT NOT NULL,
|
|
17
|
+
accepted_at TEXT,
|
|
18
|
+
accepted_by TEXT,
|
|
19
|
+
revoked_at TEXT,
|
|
20
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
21
|
+
);
|
|
22
|
+
CREATE INDEX IF NOT EXISTS workspace_invitations_workspace ON workspace_invitations(workspace_id, created_at);
|
|
23
|
+
|
|
24
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
25
|
+
id TEXT PRIMARY KEY,
|
|
26
|
+
workspace_id TEXT NOT NULL,
|
|
27
|
+
project_id TEXT,
|
|
28
|
+
actor_type TEXT NOT NULL,
|
|
29
|
+
actor_id TEXT NOT NULL,
|
|
30
|
+
action TEXT NOT NULL,
|
|
31
|
+
target_type TEXT,
|
|
32
|
+
target_id TEXT,
|
|
33
|
+
ip TEXT,
|
|
34
|
+
user_agent TEXT,
|
|
35
|
+
data_json TEXT,
|
|
36
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
37
|
+
);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS audit_log_workspace_time ON audit_log(workspace_id, created_at);
|
|
39
|
+
|
|
40
|
+
ALTER TABLE run_events ADD COLUMN actor_id TEXT;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- Plans, usage metering and retention. A workspace without a row in
|
|
2
|
+
-- workspace_plans is on the Free plan.
|
|
3
|
+
CREATE TABLE IF NOT EXISTS workspace_plans (
|
|
4
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
5
|
+
plan TEXT NOT NULL,
|
|
6
|
+
billing_interval TEXT,
|
|
7
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
8
|
+
current_period_start TEXT,
|
|
9
|
+
current_period_end TEXT,
|
|
10
|
+
spending_limit_cents INTEGER,
|
|
11
|
+
overrides_json TEXT,
|
|
12
|
+
provider TEXT,
|
|
13
|
+
provider_subscription_id TEXT,
|
|
14
|
+
pending_plan TEXT,
|
|
15
|
+
grace_until TEXT,
|
|
16
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
17
|
+
);
|
|
18
|
+
CREATE UNIQUE INDEX IF NOT EXISTS workspace_plans_subscription ON workspace_plans(provider, provider_subscription_id);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS usage_events (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
workspace_id TEXT NOT NULL,
|
|
23
|
+
project_id TEXT,
|
|
24
|
+
run_id TEXT,
|
|
25
|
+
kind TEXT NOT NULL,
|
|
26
|
+
quantity INTEGER NOT NULL,
|
|
27
|
+
source TEXT NOT NULL,
|
|
28
|
+
idempotency_key TEXT NOT NULL UNIQUE,
|
|
29
|
+
period_start TEXT NOT NULL,
|
|
30
|
+
occurred_at TEXT NOT NULL,
|
|
31
|
+
meta_json TEXT
|
|
32
|
+
);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS usage_events_period ON usage_events(workspace_id, period_start, kind);
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
CREATE TABLE IF NOT EXISTS usage_alerts_sent (
|
|
37
|
+
workspace_id TEXT NOT NULL,
|
|
38
|
+
period_start TEXT NOT NULL,
|
|
39
|
+
alert TEXT NOT NULL,
|
|
40
|
+
sent_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
41
|
+
PRIMARY KEY (workspace_id, period_start, alert)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
ALTER TABLE runs ADD COLUMN execution_mode TEXT NOT NULL DEFAULT 'self';
|
|
45
|
+
ALTER TABLE runs ADD COLUMN workspace_id TEXT;
|
|
46
|
+
ALTER TABLE runs ADD COLUMN claimed_at TEXT;
|
|
47
|
+
ALTER TABLE runs ADD COLUMN billed_at TEXT;
|
|
48
|
+
ALTER TABLE runs ADD COLUMN blocked_reason TEXT;
|
|
49
|
+
CREATE INDEX IF NOT EXISTS runs_cloud_queue ON runs(execution_mode, status, requested_at);
|
|
50
|
+
|
|
51
|
+
ALTER TABLE projects ADD COLUMN storage_mode TEXT NOT NULL DEFAULT 'byo';
|
|
52
|
+
ALTER TABLE projects ADD COLUMN default_execution_mode TEXT NOT NULL DEFAULT 'self';
|
|
53
|
+
|
|
54
|
+
UPDATE runs SET workspace_id = (SELECT workspace_id FROM projects WHERE projects.id = runs.project_id)
|
|
55
|
+
WHERE workspace_id IS NULL;
|
|
56
|
+
|
|
57
|
+
-- Where usage and billing emails go; filled in from the dashboard's sign-in.
|
|
58
|
+
ALTER TABLE aegis_users ADD COLUMN email TEXT;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Hosted runners: dispatch retries and the minutes a finished cloud run billed.
|
|
2
|
+
ALTER TABLE runs ADD COLUMN dispatch_attempts INTEGER NOT NULL DEFAULT 0;
|
|
3
|
+
ALTER TABLE runs ADD COLUMN next_dispatch_at TEXT;
|
|
4
|
+
ALTER TABLE runs ADD COLUMN billed_minutes INTEGER;
|
|
5
|
+
|
|
6
|
+
-- "valkyrie" storage keeps plans and evidence in Valkyrie's own bucket, which
|
|
7
|
+
-- is what lets a clean cloud container read them.
|
|
8
|
+
UPDATE projects SET storage_mode = 'managed' WHERE storage_provider = 'valkyrie';
|
|
9
|
+
|
|
10
|
+
-- Discovery can run on Valkyrie Cloud too, sharing the same slots and meter.
|
|
11
|
+
ALTER TABLE agent_tasks ADD COLUMN execution_mode TEXT NOT NULL DEFAULT 'self';
|
|
12
|
+
ALTER TABLE agent_tasks ADD COLUMN workspace_id TEXT;
|
|
13
|
+
ALTER TABLE agent_tasks ADD COLUMN claimed_at TEXT;
|
|
14
|
+
ALTER TABLE agent_tasks ADD COLUMN billed_at TEXT;
|
|
15
|
+
ALTER TABLE agent_tasks ADD COLUMN billed_minutes INTEGER;
|
|
16
|
+
ALTER TABLE agent_tasks ADD COLUMN blocked_reason TEXT;
|
|
17
|
+
ALTER TABLE agent_tasks ADD COLUMN dispatch_attempts INTEGER NOT NULL DEFAULT 0;
|
|
18
|
+
ALTER TABLE agent_tasks ADD COLUMN next_dispatch_at TEXT;
|
|
19
|
+
CREATE INDEX IF NOT EXISTS agent_tasks_cloud_queue ON agent_tasks(execution_mode, status, requested_at);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
-- Paid plans: checkouts, invoices and receipts, provider webhook de-duplication,
|
|
2
|
+
-- and the billing contact printed on receipts.
|
|
3
|
+
ALTER TABLE workspace_plans ADD COLUMN billing_email TEXT;
|
|
4
|
+
ALTER TABLE workspace_plans ADD COLUMN billing_name TEXT;
|
|
5
|
+
ALTER TABLE workspace_plans ADD COLUMN billing_address TEXT;
|
|
6
|
+
ALTER TABLE workspace_plans ADD COLUMN tax_id TEXT;
|
|
7
|
+
-- The payment that paid for the current period, for pro-rata refunds on upgrade.
|
|
8
|
+
ALTER TABLE workspace_plans ADD COLUMN last_payment_json TEXT;
|
|
9
|
+
-- A cancellation or downgrade takes effect when the period ends.
|
|
10
|
+
ALTER TABLE workspace_plans ADD COLUMN cancel_at_period_end INTEGER NOT NULL DEFAULT 0;
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS billing_checkouts (
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
15
|
+
plan TEXT NOT NULL,
|
|
16
|
+
billing_interval TEXT NOT NULL,
|
|
17
|
+
provider TEXT NOT NULL,
|
|
18
|
+
provider_subscription_id TEXT,
|
|
19
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
20
|
+
-- The subscription this checkout replaces (an upgrade), settled once it's paid.
|
|
21
|
+
replaces_subscription_id TEXT,
|
|
22
|
+
replaced_payment_json TEXT,
|
|
23
|
+
replaced_cancelled_at TEXT,
|
|
24
|
+
refund_json TEXT,
|
|
25
|
+
settled_at TEXT,
|
|
26
|
+
created_by TEXT NOT NULL,
|
|
27
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
completed_at TEXT
|
|
29
|
+
);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS billing_checkouts_workspace ON billing_checkouts(workspace_id, created_at);
|
|
31
|
+
CREATE UNIQUE INDEX IF NOT EXISTS billing_checkouts_subscription ON billing_checkouts(provider, provider_subscription_id);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE IF NOT EXISTS invoices (
|
|
34
|
+
id TEXT PRIMARY KEY,
|
|
35
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
36
|
+
number TEXT NOT NULL UNIQUE,
|
|
37
|
+
-- "subscription": a plan payment PayPal already took. "usage": extra usage billed after the month.
|
|
38
|
+
kind TEXT NOT NULL,
|
|
39
|
+
status TEXT NOT NULL,
|
|
40
|
+
plan TEXT,
|
|
41
|
+
period_start TEXT NOT NULL,
|
|
42
|
+
period_end TEXT NOT NULL,
|
|
43
|
+
currency TEXT NOT NULL DEFAULT 'USD',
|
|
44
|
+
total_cents INTEGER NOT NULL,
|
|
45
|
+
lines_json TEXT NOT NULL,
|
|
46
|
+
provider TEXT,
|
|
47
|
+
provider_ref TEXT,
|
|
48
|
+
provider_url TEXT,
|
|
49
|
+
due_at TEXT,
|
|
50
|
+
paid_at TEXT,
|
|
51
|
+
refunded_cents INTEGER NOT NULL DEFAULT 0,
|
|
52
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
53
|
+
);
|
|
54
|
+
CREATE INDEX IF NOT EXISTS invoices_workspace ON invoices(workspace_id, created_at);
|
|
55
|
+
CREATE UNIQUE INDEX IF NOT EXISTS invoices_provider_ref ON invoices(provider, provider_ref);
|
|
56
|
+
CREATE UNIQUE INDEX IF NOT EXISTS invoices_usage_period ON invoices(workspace_id, kind, period_start);
|
|
57
|
+
|
|
58
|
+
CREATE TABLE IF NOT EXISTS billing_events (
|
|
59
|
+
provider TEXT NOT NULL,
|
|
60
|
+
event_id TEXT NOT NULL,
|
|
61
|
+
event_type TEXT NOT NULL,
|
|
62
|
+
received_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
63
|
+
PRIMARY KEY (provider, event_id)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
-- Projects beyond a downgraded plan's limit are kept, read-only.
|
|
67
|
+
ALTER TABLE projects ADD COLUMN locked_at TEXT;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- Work that talks to other services (Slack, GitHub, email) goes through an
|
|
2
|
+
-- outbox, so a slow or failing service never fails the request that caused it.
|
|
3
|
+
CREATE TABLE IF NOT EXISTS outbox (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
kind TEXT NOT NULL,
|
|
6
|
+
payload_json TEXT NOT NULL,
|
|
7
|
+
dedupe_key TEXT UNIQUE,
|
|
8
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
9
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
10
|
+
next_attempt_at TEXT NOT NULL,
|
|
11
|
+
locked_until TEXT,
|
|
12
|
+
last_error TEXT,
|
|
13
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
done_at TEXT
|
|
15
|
+
);
|
|
16
|
+
CREATE INDEX IF NOT EXISTS outbox_due ON outbox(status, next_attempt_at);
|
|
17
|
+
|
|
18
|
+
CREATE TABLE IF NOT EXISTS slack_installations (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
21
|
+
team_id TEXT NOT NULL,
|
|
22
|
+
team_name TEXT,
|
|
23
|
+
channel_id TEXT NOT NULL,
|
|
24
|
+
channel_name TEXT,
|
|
25
|
+
bot_token_ciphertext TEXT NOT NULL,
|
|
26
|
+
bot_token_iv TEXT NOT NULL,
|
|
27
|
+
installed_by TEXT NOT NULL,
|
|
28
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
29
|
+
revoked_at TEXT,
|
|
30
|
+
revoked_reason TEXT
|
|
31
|
+
);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS slack_installations_workspace ON slack_installations(workspace_id);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS alert_rules (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
37
|
+
-- Null means every project in the workspace.
|
|
38
|
+
project_id TEXT,
|
|
39
|
+
event TEXT NOT NULL,
|
|
40
|
+
channel TEXT NOT NULL,
|
|
41
|
+
-- A Slack installation id, or an email address.
|
|
42
|
+
target TEXT NOT NULL,
|
|
43
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
44
|
+
created_by TEXT NOT NULL,
|
|
45
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
+
UNIQUE (workspace_id, project_id, event, channel, target)
|
|
47
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-- Which repositories start runs, and which GitHub check a run reports to.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS project_repo_bindings (
|
|
3
|
+
id TEXT PRIMARY KEY,
|
|
4
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
5
|
+
installation_id INTEGER NOT NULL,
|
|
6
|
+
repo_full_name TEXT NOT NULL,
|
|
7
|
+
-- JSON array of plan ids; null runs every published plan.
|
|
8
|
+
plan_ids_json TEXT,
|
|
9
|
+
environment_id TEXT,
|
|
10
|
+
-- pull_request: every push to an open PR. deployment: when a deployment succeeds.
|
|
11
|
+
trigger TEXT NOT NULL DEFAULT 'pull_request',
|
|
12
|
+
-- e.g. https://pr-{number}.preview.example.com; null uses the environment or the deployment's URL.
|
|
13
|
+
base_url_template TEXT,
|
|
14
|
+
execution_mode TEXT NOT NULL DEFAULT 'cloud',
|
|
15
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
16
|
+
created_by TEXT NOT NULL,
|
|
17
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
18
|
+
UNIQUE (project_id, repo_full_name, trigger)
|
|
19
|
+
);
|
|
20
|
+
CREATE INDEX IF NOT EXISTS project_repo_bindings_repo ON project_repo_bindings(repo_full_name);
|
|
21
|
+
|
|
22
|
+
ALTER TABLE runs ADD COLUMN trigger_source TEXT;
|
|
23
|
+
ALTER TABLE runs ADD COLUMN repo_full_name TEXT;
|
|
24
|
+
ALTER TABLE runs ADD COLUMN commit_sha TEXT;
|
|
25
|
+
ALTER TABLE runs ADD COLUMN pr_number INTEGER;
|
|
26
|
+
ALTER TABLE runs ADD COLUMN github_installation_id INTEGER;
|
|
27
|
+
ALTER TABLE runs ADD COLUMN check_run_id INTEGER;
|
|
28
|
+
CREATE INDEX IF NOT EXISTS runs_check_run ON runs(check_run_id);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Bug reports and feedback sent from the dashboard, and the GitHub issue each became.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS feedback_reports (
|
|
3
|
+
id TEXT PRIMARY KEY,
|
|
4
|
+
aegis_id TEXT NOT NULL,
|
|
5
|
+
workspace_id TEXT,
|
|
6
|
+
project_id TEXT,
|
|
7
|
+
run_id TEXT,
|
|
8
|
+
kind TEXT NOT NULL,
|
|
9
|
+
rating INTEGER,
|
|
10
|
+
category TEXT,
|
|
11
|
+
message TEXT NOT NULL,
|
|
12
|
+
page TEXT,
|
|
13
|
+
plan TEXT,
|
|
14
|
+
-- Contact details only when the person chose to give them.
|
|
15
|
+
contact TEXT,
|
|
16
|
+
data_json TEXT NOT NULL DEFAULT '{}',
|
|
17
|
+
screenshot_keys_json TEXT NOT NULL DEFAULT '[]',
|
|
18
|
+
fingerprint TEXT NOT NULL,
|
|
19
|
+
duplicate_of TEXT,
|
|
20
|
+
github_issue_number INTEGER,
|
|
21
|
+
github_issue_url TEXT,
|
|
22
|
+
status TEXT NOT NULL DEFAULT 'new',
|
|
23
|
+
ip TEXT,
|
|
24
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
25
|
+
closed_at TEXT
|
|
26
|
+
);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS feedback_reports_person ON feedback_reports(aegis_id, created_at);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS feedback_reports_fingerprint ON feedback_reports(fingerprint, created_at);
|
|
29
|
+
CREATE INDEX IF NOT EXISTS feedback_reports_issue ON feedback_reports(github_issue_number);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- Device clouds a workspace connects, app builds to install, and sessions on
|
|
2
|
+
-- Valkyrie's own device cloud (metered in device minutes).
|
|
3
|
+
CREATE TABLE IF NOT EXISTS device_cloud_credentials (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
6
|
+
provider TEXT NOT NULL,
|
|
7
|
+
label TEXT NOT NULL,
|
|
8
|
+
username TEXT NOT NULL,
|
|
9
|
+
project_arn TEXT,
|
|
10
|
+
secret_ciphertext TEXT NOT NULL,
|
|
11
|
+
secret_iv TEXT NOT NULL,
|
|
12
|
+
created_by TEXT NOT NULL,
|
|
13
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
last_verified_at TEXT,
|
|
15
|
+
revoked_at TEXT
|
|
16
|
+
);
|
|
17
|
+
CREATE INDEX IF NOT EXISTS device_cloud_credentials_workspace ON device_cloud_credentials(workspace_id);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS app_builds (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
22
|
+
platform TEXT NOT NULL,
|
|
23
|
+
filename TEXT NOT NULL,
|
|
24
|
+
object_key TEXT NOT NULL,
|
|
25
|
+
size_bytes INTEGER NOT NULL,
|
|
26
|
+
sha256 TEXT NOT NULL,
|
|
27
|
+
-- Uploads already made to device clouds, so a build isn't sent twice.
|
|
28
|
+
provider_refs_json TEXT NOT NULL DEFAULT '{}',
|
|
29
|
+
uploaded_by TEXT NOT NULL,
|
|
30
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
31
|
+
deleted_at TEXT
|
|
32
|
+
);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS app_builds_project ON app_builds(project_id, created_at);
|
|
34
|
+
|
|
35
|
+
CREATE TABLE IF NOT EXISTS valkyrie_device_sessions (
|
|
36
|
+
id TEXT PRIMARY KEY,
|
|
37
|
+
run_id TEXT NOT NULL,
|
|
38
|
+
project_id TEXT NOT NULL,
|
|
39
|
+
workspace_id TEXT NOT NULL,
|
|
40
|
+
device_name TEXT NOT NULL,
|
|
41
|
+
session_arn TEXT NOT NULL,
|
|
42
|
+
status TEXT NOT NULL DEFAULT 'starting',
|
|
43
|
+
metered_minutes INTEGER,
|
|
44
|
+
billed_at TEXT,
|
|
45
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
+
finished_at TEXT
|
|
47
|
+
);
|
|
48
|
+
CREATE INDEX IF NOT EXISTS valkyrie_device_sessions_open ON valkyrie_device_sessions(status, created_at);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- Enterprise SSO/SCIM: a workspace linked to an Aegis organization, how IdP
|
|
2
|
+
-- groups map to workspace roles, and who was removed by the IdP.
|
|
3
|
+
ALTER TABLE workspaces ADD COLUMN aegis_org_id TEXT;
|
|
4
|
+
-- Role for organization members whose groups match no mapping ('none' = no access).
|
|
5
|
+
ALTER TABLE workspaces ADD COLUMN sso_default_role TEXT NOT NULL DEFAULT 'member';
|
|
6
|
+
-- What Aegis was last told ('on' / 'off'), and when a plan that lost SSO stops using it.
|
|
7
|
+
ALTER TABLE workspaces ADD COLUMN sso_entitlement TEXT;
|
|
8
|
+
ALTER TABLE workspaces ADD COLUMN sso_grace_until TEXT;
|
|
9
|
+
CREATE UNIQUE INDEX IF NOT EXISTS workspaces_aegis_org ON workspaces(aegis_org_id) WHERE aegis_org_id IS NOT NULL;
|
|
10
|
+
|
|
11
|
+
-- 'invite' rows are managed by people; 'sso' rows follow the IdP.
|
|
12
|
+
ALTER TABLE workspace_memberships ADD COLUMN source TEXT NOT NULL DEFAULT 'invite';
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS workspace_group_roles (
|
|
15
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
16
|
+
group_name TEXT NOT NULL,
|
|
17
|
+
role TEXT NOT NULL,
|
|
18
|
+
created_by TEXT NOT NULL,
|
|
19
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
PRIMARY KEY (workspace_id, group_name)
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
-- Set when the IdP deprovisions someone; their dashboard sign-ins are refused until reactivated.
|
|
24
|
+
ALTER TABLE aegis_users ADD COLUMN deprovisioned_at TEXT;
|
|
25
|
+
|
|
26
|
+
-- Signed events already handled, so a replayed delivery does nothing.
|
|
27
|
+
CREATE TABLE IF NOT EXISTS aegis_events (
|
|
28
|
+
id TEXT PRIMARY KEY,
|
|
29
|
+
type TEXT NOT NULL,
|
|
30
|
+
received_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
31
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- Domains a workspace has proven it controls, by DNS TXT record. Required
|
|
2
|
+
-- before Valkyrie Cloud (its own IPs) will explore or run against a host on
|
|
3
|
+
-- that domain, so a workspace can't point Valkyrie's cloud infrastructure at
|
|
4
|
+
-- a site it doesn't own. Self-hosted runs and explorations are unaffected —
|
|
5
|
+
-- those use the customer's own machine or CI, never Valkyrie's.
|
|
6
|
+
CREATE TABLE IF NOT EXISTS workspace_domains (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
9
|
+
domain TEXT NOT NULL,
|
|
10
|
+
verification_token TEXT NOT NULL,
|
|
11
|
+
status TEXT NOT NULL DEFAULT 'pending', -- pending | verified
|
|
12
|
+
created_by TEXT,
|
|
13
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
verified_at TEXT,
|
|
15
|
+
last_check_error TEXT
|
|
16
|
+
);
|
|
17
|
+
CREATE UNIQUE INDEX IF NOT EXISTS workspace_domains_unique ON workspace_domains(workspace_id, domain);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS workspace_domains_by_workspace ON workspace_domains(workspace_id, status);
|