Forge
csharp3407750f
1using AgentForge.Data.Entities;
2using Microsoft.EntityFrameworkCore;
3
4namespace AgentForge.Data;
5
6public sealed class ForgeDbContext(DbContextOptions<ForgeDbContext> options) : DbContext(options)
7{
8 public DbSet<ForgeRepoEntity> Repos => Set<ForgeRepoEntity>();
9
10 public DbSet<ForgeOrgEntity> Orgs => Set<ForgeOrgEntity>();
11
12 public DbSet<ForgeOrgMemberEntity> OrgMembers => Set<ForgeOrgMemberEntity>();
13
14 public DbSet<ForgeInstanceAdminEntity> InstanceAdmins => Set<ForgeInstanceAdminEntity>();
15
16 public DbSet<ForgeRepoGroupEntity> RepoGroups => Set<ForgeRepoGroupEntity>();
17
18 public DbSet<ForgeIssueEntity> Issues => Set<ForgeIssueEntity>();
19
20 public DbSet<ForgeIssueCommentEntity> IssueComments => Set<ForgeIssueCommentEntity>();
21
22 public DbSet<ForgeMergeRequestEntity> MergeRequests => Set<ForgeMergeRequestEntity>();
23
24 public DbSet<ForgeMergeRequestCommentEntity> MergeRequestComments => Set<ForgeMergeRequestCommentEntity>();
25
26 public DbSet<ForgeCiRunEntity> CiRuns => Set<ForgeCiRunEntity>();
27
28 public DbSet<ForgeCiDefinitionEntity> CiDefinitions => Set<ForgeCiDefinitionEntity>();
29
30 public DbSet<ForgeCiPipelineRunEntity> CiPipelineRuns => Set<ForgeCiPipelineRunEntity>();
31
32 public DbSet<ForgeCiStepRunEntity> CiStepRuns => Set<ForgeCiStepRunEntity>();
33
34 public DbSet<ForgeApiTokenEntity> ApiTokens => Set<ForgeApiTokenEntity>();
35
36 public DbSet<ForgeDeviceLoginEntity> DeviceLogins => Set<ForgeDeviceLoginEntity>();
37
38 public DbSet<ForgeOAuthStateEntity> OAuthStates => Set<ForgeOAuthStateEntity>();
39
40 public DbSet<ForgeIdentityEntity> Identities => Set<ForgeIdentityEntity>();
41
42 public DbSet<ForgeCommitProvenanceEntity> CommitProvenance => Set<ForgeCommitProvenanceEntity>();
43
44 protected override void OnModelCreating(ModelBuilder modelBuilder)
45 {
46 modelBuilder.Entity<ForgeOrgEntity>(e =>
47 {
48 e.ToTable("orgs");
49 e.HasKey(x => x.Id);
50 e.HasIndex(x => x.Slug).IsUnique();
51 e.Property(x => x.DefaultVisibility).HasConversion(ForgeValueConverters.RepoVisibility);
52 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
53 });
54
55 modelBuilder.Entity<ForgeOrgMemberEntity>(e =>
56 {
57 e.ToTable("org_members");
58 e.HasKey(x => x.Id);
59 e.HasIndex(x => new { x.OrgId, x.IdentityId }).IsUnique();
60 e.Property(x => x.Role).HasConversion(ForgeValueConverters.ForgeOrgRole);
61 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
62 e.HasOne(x => x.Org).WithMany(x => x.Members).HasForeignKey(x => x.OrgId);
63 e.HasOne(x => x.Identity).WithMany().HasForeignKey(x => x.IdentityId);
64 });
65
66 modelBuilder.Entity<ForgeInstanceAdminEntity>(e =>
67 {
68 e.ToTable("instance_admins");
69 e.HasKey(x => x.Id);
70 e.HasIndex(x => x.IdentityId).IsUnique();
71 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
72 e.HasOne(x => x.Identity).WithMany().HasForeignKey(x => x.IdentityId);
73 });
74
75 modelBuilder.Entity<ForgeRepoEntity>(e =>
76 {
77 e.ToTable("repos");
78 e.HasKey(x => x.Id);
79 e.HasIndex(x => x.Name).IsUnique();
80 e.Property(x => x.DriveMode).HasConversion(ForgeValueConverters.DriveMode);
81 e.Property(x => x.Visibility).HasConversion(ForgeValueConverters.RepoVisibility);
82 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
83 e.HasOne(x => x.Org).WithMany(x => x.Repos).HasForeignKey(x => x.OrgId);
84 e.HasOne(x => x.Group).WithMany(x => x.Repos).HasForeignKey(x => x.GroupId);
85 });
86
87 modelBuilder.Entity<ForgeRepoGroupEntity>(e =>
88 {
89 e.ToTable("repo_groups");
90 e.HasKey(x => x.Id);
91 e.HasIndex(x => new { x.OrgId, x.ParentGroupKey, x.Slug }).IsUnique();
92 e.Property(x => x.DefaultVisibility).HasConversion(ForgeValueConverters.NullableRepoVisibility);
93 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
94 e.HasOne(x => x.Org).WithMany(x => x.RepoGroups).HasForeignKey(x => x.OrgId);
95 e.HasOne(x => x.Parent).WithMany(x => x.Children).HasForeignKey(x => x.ParentGroupId);
96 });
97
98 modelBuilder.Entity<ForgeIssueEntity>(e =>
99 {
100 e.ToTable("issues");
101 e.HasKey(x => x.Id);
102 e.HasIndex(x => new { x.RepoId, x.Number }).IsUnique();
103 e.HasIndex(x => x.RepoId);
104 e.Property(x => x.Status).HasConversion(ForgeValueConverters.IssueStatus);
105 e.Property(x => x.Anchors).HasConversion(ForgeValueConverters.Anchors);
106 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
107 e.HasOne(x => x.Repo).WithMany(x => x.Issues).HasForeignKey(x => x.RepoId);
108 });
109
110 modelBuilder.Entity<ForgeIssueCommentEntity>(e =>
111 {
112 e.ToTable("issue_comments");
113 e.HasKey(x => x.Id);
114 e.HasIndex(x => x.IssueId);
115 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
116 e.HasOne(x => x.Issue).WithMany(x => x.Comments).HasForeignKey(x => x.IssueId);
117 });
118
119 modelBuilder.Entity<ForgeMergeRequestEntity>(e =>
120 {
121 e.ToTable("merge_requests");
122 e.HasKey(x => x.Id);
123 e.HasIndex(x => new { x.RepoId, x.Number }).IsUnique();
124 e.HasIndex(x => x.RepoId);
125 e.Property(x => x.Status).HasConversion(ForgeValueConverters.MergeRequestStatus);
126 e.Property(x => x.Anchors).HasConversion(ForgeValueConverters.Anchors);
127 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
128 e.HasOne(x => x.Repo).WithMany(x => x.MergeRequests).HasForeignKey(x => x.RepoId);
129 });
130
131 modelBuilder.Entity<ForgeMergeRequestCommentEntity>(e =>
132 {
133 e.ToTable("merge_request_comments");
134 e.HasKey(x => x.Id);
135 e.HasIndex(x => x.MergeRequestId);
136 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
137 e.HasOne(x => x.MergeRequest).WithMany(x => x.Comments).HasForeignKey(x => x.MergeRequestId);
138 });
139
140 modelBuilder.Entity<ForgeCiRunEntity>(e =>
141 {
142 e.ToTable("ci_runs");
143 e.HasKey(x => x.Id);
144 e.HasIndex(x => new { x.RepoId, x.MrNumber });
145 e.Property(x => x.Status).HasConversion(ForgeValueConverters.CiRunStatus);
146 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
147 e.Property(x => x.UpdatedAt).HasConversion(ForgeValueConverters.Timestamp);
148 e.HasOne(x => x.Repo).WithMany().HasForeignKey(x => x.RepoId);
149 });
150
151 modelBuilder.Entity<ForgeCiDefinitionEntity>(e =>
152 {
153 e.ToTable("ci_definitions");
154 e.HasKey(x => x.Id);
155 e.HasIndex(x => new { x.RepoId, x.Name }).IsUnique();
156 e.HasIndex(x => x.RepoId);
157 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
158 e.Property(x => x.UpdatedAt).HasConversion(ForgeValueConverters.Timestamp);
159 e.HasOne(x => x.Repo).WithMany().HasForeignKey(x => x.RepoId);
160 });
161
162 modelBuilder.Entity<ForgeCiPipelineRunEntity>(e =>
163 {
164 e.ToTable("ci_pipeline_runs");
165 e.HasKey(x => x.Id);
166 e.HasIndex(x => x.RepoId);
167 e.HasIndex(x => new { x.RepoId, x.CreatedAt });
168 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
169 e.Property(x => x.UpdatedAt).HasConversion(ForgeValueConverters.Timestamp);
170 e.Property(x => x.StartedAt).HasConversion(ForgeValueConverters.NullableTimestamp);
171 e.Property(x => x.FinishedAt).HasConversion(ForgeValueConverters.NullableTimestamp);
172 e.HasOne(x => x.Repo).WithMany().HasForeignKey(x => x.RepoId);
173 e.HasMany(x => x.Steps).WithOne(x => x.Run).HasForeignKey(x => x.RunId);
174 });
175
176 modelBuilder.Entity<ForgeCiStepRunEntity>(e =>
177 {
178 e.ToTable("ci_step_runs");
179 e.HasKey(x => x.Id);
180 e.HasIndex(x => x.RunId);
181 e.HasIndex(x => new { x.RunId, x.OrderIndex }).IsUnique();
182 e.Property(x => x.StartedAt).HasConversion(ForgeValueConverters.NullableTimestamp);
183 e.Property(x => x.FinishedAt).HasConversion(ForgeValueConverters.NullableTimestamp);
184 });
185
186 modelBuilder.Entity<ForgeApiTokenEntity>(e =>
187 {
188 e.ToTable("api_tokens");
189 e.HasKey(x => x.Id);
190 e.HasIndex(x => x.TokenHash).IsUnique();
191 e.Property(x => x.Scopes).HasConversion(ForgeValueConverters.ForgeScope);
192 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
193 e.Property(x => x.RevokedAt).HasConversion(ForgeValueConverters.Timestamp);
194 });
195
196 modelBuilder.Entity<ForgeDeviceLoginEntity>(e =>
197 {
198 e.ToTable("device_logins");
199 e.HasKey(x => x.Id);
200 e.HasIndex(x => x.DeviceCodeHash).IsUnique();
201 e.HasIndex(x => x.UserCode);
202 e.Property(x => x.Status).HasConversion<int>();
203 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
204 e.Property(x => x.ExpiresAt).HasConversion(ForgeValueConverters.Timestamp);
205 e.Property(x => x.ApprovedAt).HasConversion(ForgeValueConverters.Timestamp);
206 });
207
208 modelBuilder.Entity<ForgeOAuthStateEntity>(e =>
209 {
210 e.ToTable("oauth_states");
211 e.HasKey(x => x.Id);
212 e.HasIndex(x => x.State).IsUnique();
213 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
214 e.Property(x => x.ExpiresAt).HasConversion(ForgeValueConverters.Timestamp);
215 });
216
217 modelBuilder.Entity<ForgeIdentityEntity>(e =>
218 {
219 e.ToTable("identities");
220 e.HasKey(x => x.Id);
221 e.HasIndex(x => new { x.Provider, x.SubjectId }).IsUnique();
222 e.Property(x => x.CreatedAt).HasConversion(ForgeValueConverters.Timestamp);
223 e.Property(x => x.LastLoginAt).HasConversion(ForgeValueConverters.Timestamp);
224 });
225
226 modelBuilder.Entity<ForgeCommitProvenanceEntity>(e =>
227 {
228 e.ToTable("commit_provenance");
229 e.HasKey(x => x.Id);
230 e.HasIndex(x => new { x.RepoId, x.Sha }).IsUnique();
231 e.HasIndex(x => x.RepoId);
232 e.Property(x => x.IssueNumbers).HasConversion(ForgeValueConverters.IntList);
233 e.Property(x => x.Anchors).HasConversion(ForgeValueConverters.Anchors);
234 e.Property(x => x.RecordedAt).HasConversion(ForgeValueConverters.Timestamp);
235 e.HasOne(x => x.Repo).WithMany().HasForeignKey(x => x.RepoId);
236 });
237 }
238}
239
View only · write via MCP/CIDE