-- Repos: workspace-scoped cache of the repositories pulled from each -- connected provider (GitHub / Gitea / GitLab). One row per (connection, -- external_id). The provider PAT itself never lives here — it's already -- in the secret broker via app_connections.secret_ref (see 0007). -- -- Sync flow: -- POST /api/repos/connections/:id/sync → provider API list → upsert. -- Removed-upstream rows stay for now (v1); a future flag can prune them. -- -- repo_connections wraps an app_connections row with the repo-specific -- config: which owner (org/user) to pull from, provider base URL for -- self-hosted Gitea/GitLab instances, and last-sync bookkeeping. CREATE TABLE repo_connections ( id UUID PRIMARY KEY, workspace_id UUID NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE, app_connection_id UUID NOT NULL REFERENCES app_connections (id) ON DELETE CASCADE, provider TEXT NOT NULL, -- 'github' | 'gitea' | 'gitlab' -- Optional owner (org or user). When NULL, the provider fetches "all -- repos the token can see" (e.g. GitHub /user/repos). owner TEXT, -- Optional base URL for self-hosted providers (e.g. https://git.redclaw.dev). base_url TEXT, label TEXT NOT NULL DEFAULT '', last_synced_at TIMESTAMPTZ, last_sync_error TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX repo_connections_workspace_idx ON repo_connections (workspace_id, created_at DESC); CREATE TABLE repos ( id UUID PRIMARY KEY, workspace_id UUID NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE, connection_id UUID NOT NULL REFERENCES repo_connections (id) ON DELETE CASCADE, provider TEXT NOT NULL, -- 'github' | 'gitea' | 'gitlab' -- Provider-side stable id (numeric on GitHub, integer on Gitea/GitLab). -- Stored as TEXT so we don't care which flavor the provider uses. external_id TEXT NOT NULL, owner TEXT NOT NULL, -- org or user login name TEXT NOT NULL, -- repo slug description TEXT, default_branch TEXT, clone_url TEXT, html_url TEXT, private BOOLEAN NOT NULL DEFAULT false, stars INTEGER NOT NULL DEFAULT 0, forks INTEGER NOT NULL DEFAULT 0, -- Provider's own `updated_at` (last push / edit), NOT the sync time. provider_updated_at TIMESTAMPTZ, last_synced_at TIMESTAMPTZ NOT NULL DEFAULT now(), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (connection_id, external_id) ); CREATE INDEX repos_workspace_idx ON repos (workspace_id, provider_updated_at DESC NULLS LAST); -- Fast per-connection list (sidebar grouping). CREATE INDEX repos_connection_idx ON repos (connection_id, name);