Skip to content

Data Model

The DevOps / GitOps Platform stores delivery metadata in relational stores while the authoritative content (source trees, packages, images, infra state) lives in purpose-built systems (Azure DevOps Git, Azure Artifacts, ACR, Pulumi backend). This page describes the logical model that ties those records together for traceability.

Target Architecture — Final-State Design

Each microservice owns its tables in a dedicated schema; the diagram below is a logical view across service boundaries. Cross-service references are by identifier, resolved through events — not foreign keys across databases.

Logical Model

The model is anchored by the delivery chain: a Repository holds Branches; Commits land on branches; PullRequests merge branches; merges trigger PipelineRuns; runs produce BuildResults; builds feed ReleasePlans; releases promote through environments and reconcile via GitOps.

erDiagram
    Repository ||--o{ Branch : contains
    Repository ||--o{ Commit : tracks
    Repository ||--o{ PullRequest : hosts
    Branch ||--o{ Commit : "receives"
    PullRequest }o--|| Branch : "source"
    PullRequest }o--|| Branch : "target"
    Repository ||--o{ PipelineRun : "builds"
    PipelineRun ||--o{ BuildResult : "produces"
    BuildResult ||--o{ ReleasePlan : "feeds"

    Repository {
        string repositoryId PK
        string tenantId
        string projectId
        string moduleId
        string name
        string provider
        string defaultBranch
        string status
    }
    Branch {
        string branchId PK
        string repositoryId FK
        string name
        string fromCommitSha
        bool isProtected
    }
    Commit {
        string commitId PK
        string repositoryId FK
        string branch
        string sha
        string artifactId
        string treeHash
    }
    PullRequest {
        string pullRequestId PK
        string repositoryId FK
        int number
        string sourceBranch
        string targetBranch
        string status
    }
    PipelineRun {
        string pipelineRunId PK
        string pipelineId
        string repositoryId FK
        string branch
        string status
    }
    BuildResult {
        string buildResultId PK
        string pipelineRunId FK
        string moduleId
        string status
        string logsUri
    }
    ReleasePlan {
        string releaseId PK
        string buildResultId FK
        string moduleId
        string version
        string targetEnvironment
        string status
    }
Hold "Alt" / "Option" to enable pan & zoom

Identifiers & Keys

  • Primary keys use prefixed identifiers per the naming conventions (repo-, branch-, commit-, pr-, run-, build-, rel-).
  • Every row carries tenantId and (where applicable) projectId / moduleId for partitioning and isolation.
  • artifactId, buildResultId, and releaseId form the lineage spine linking back to the Knowledge Platform graph.

Indexes

Table Index Purpose
Repository (tenantId, projectId, name) unique Enforce unique repo names; tenant-scoped lookups
Branch (repositoryId, name) unique Branch resolution
Commit (repositoryId, sha) unique; (artifactId) Lineage and dedup
PullRequest (repositoryId, number) unique; (tenantId, status) PR queries and dashboards
PipelineRun (pipelineId, buildNumber); (tenantId, status) Run tracking
BuildResult (pipelineRunId) unique; (moduleId, completedAt) Latest build per module
ReleasePlan (moduleId, targetEnvironment, version) unique; (tenantId, status) Release governance queries

Retention

Data Retention Notes
Repository / Branch metadata Lifetime of project Source of truth in Azure DevOps
Commit metadata Lifetime of project Content in Git
PullRequest records 24 months after merge/abandon Governance audit
PipelineRun / BuildResult 12 months hot, then archived Logs in Blob with lifecycle policy
ReleasePlan / Approval / Promotion 7 years Compliance / audit
GitOpsSyncState Current + 90-day history Drift forensics

Multi-Tenancy

  • Tenant isolation is enforced at the data layer via ConnectSoft.Extensions.Saas.NHibernate global filters on tenantId; no query can cross tenants.
  • Large tenants can be sharded by tenantId onto dedicated database instances; the logical model is unchanged.
  • All cross-service joins happen at the application layer using identifiers, preserving service autonomy and tenant boundaries.

Pillar Alignment

  • Traceability — the lineage spine (artifactId → commit → build → release) is queryable end to end.
  • Multi-tenant scale — partitioning keys and global filters guarantee isolation while allowing horizontal scale.
  • Governance — long retention on releases/approvals satisfies audit and compliance needs.