-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTestDbContext.cs
More file actions
1349 lines (1076 loc) · 37.3 KB
/
TestDbContext.cs
File metadata and controls
1349 lines (1076 loc) · 37.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
using Microsoft.EntityFrameworkCore;
namespace SchemaMagic.Examples;
public class TestDbContext : DbContext
{
// Core entities with extensive properties
public DbSet<User> Users { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<Task> Tasks { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Attachment> Attachments { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<TaskTag> TaskTags { get; set; }
public DbSet<UserProject> UserProjects { get; set; }
public DbSet<AuditLog> AuditLogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure many-to-many relationships
modelBuilder.Entity<TaskTag>()
.HasKey(tt => new { tt.TaskId, tt.TagId });
modelBuilder.Entity<TaskTag>()
.HasOne(tt => tt.Task)
.WithMany(t => t.TaskTags)
.HasForeignKey(tt => tt.TaskId);
modelBuilder.Entity<TaskTag>()
.HasOne(tt => tt.Tag)
.WithMany(t => t.TaskTags)
.HasForeignKey(tt => tt.TagId);
modelBuilder.Entity<UserProject>()
.HasKey(up => new { up.UserId, up.ProjectId });
modelBuilder.Entity<UserProject>()
.HasOne(up => up.User)
.WithMany(u => u.UserProjects)
.HasForeignKey(up => up.UserId);
modelBuilder.Entity<UserProject>()
.HasOne(up => up.Project)
.WithMany(p => p.UserProjects)
.HasForeignKey(up => up.ProjectId);
// Configure foreign key relationships
modelBuilder.Entity<Department>()
.HasOne(d => d.Company)
.WithMany(c => c.Departments)
.HasForeignKey(d => d.CompanyId);
modelBuilder.Entity<User>()
.HasOne(u => u.Department)
.WithMany(d => d.Employees)
.HasForeignKey(u => u.DepartmentId);
modelBuilder.Entity<Project>()
.HasOne(p => p.Company)
.WithMany(c => c.Projects)
.HasForeignKey(p => p.CompanyId);
modelBuilder.Entity<Project>()
.HasOne(p => p.ProjectManager)
.WithMany(u => u.ManagedProjects)
.HasForeignKey(p => p.ProjectManagerId);
modelBuilder.Entity<Task>()
.HasOne(t => t.Project)
.WithMany(p => p.Tasks)
.HasForeignKey(t => t.ProjectId);
modelBuilder.Entity<Task>()
.HasOne(t => t.AssignedTo)
.WithMany(u => u.AssignedTasks)
.HasForeignKey(t => t.AssignedToId);
modelBuilder.Entity<Task>()
.HasOne(t => t.CreatedBy)
.WithMany(u => u.CreatedTasks)
.HasForeignKey(t => t.CreatedById);
modelBuilder.Entity<Document>()
.HasOne(d => d.Project)
.WithMany(p => p.Documents)
.HasForeignKey(d => d.ProjectId);
modelBuilder.Entity<Document>()
.HasOne(d => d.UploadedBy)
.WithMany(u => u.UploadedDocuments)
.HasForeignKey(d => d.UploadedById);
modelBuilder.Entity<Comment>()
.HasOne(c => c.Task)
.WithMany(t => t.Comments)
.HasForeignKey(c => c.TaskId);
modelBuilder.Entity<Comment>()
.HasOne(c => c.Author)
.WithMany(u => u.Comments)
.HasForeignKey(c => c.AuthorId);
modelBuilder.Entity<Attachment>()
.HasOne(a => a.Comment)
.WithMany(c => c.Attachments)
.HasForeignKey(a => a.CommentId);
modelBuilder.Entity<Attachment>()
.HasOne(a => a.UploadedBy)
.WithMany(u => u.UploadedAttachments)
.HasForeignKey(a => a.UploadedById);
modelBuilder.Entity<AuditLog>()
.HasOne(a => a.User)
.WithMany(u => u.AuditLogs)
.HasForeignKey(a => a.UserId);
}
}
/// <summary>
/// Represents a business organization that manages departments and projects
/// </summary>
[Comment("Business organization entity - root tenant for multi-company operations")]
public class Company
{
[Comment("Primary key - unique company identifier")]
public int Id { get; set; }
/// <summary>
/// Official company name as registered
/// </summary>
[Comment("Official business name")]
public string Name { get; set; } = string.Empty;
[Comment("Industry sector classification")]
public string Industry { get; set; } = string.Empty;
/// <summary>
/// Street address of company headquarters
/// </summary>
public string Address { get; set; } = string.Empty;
[Comment("City where company is headquartered")]
public string City { get; set; } = string.Empty;
/// <summary>
/// State or province
/// </summary>
public string State { get; set; } = string.Empty;
[Comment("ZIP or postal code")]
public string PostalCode { get; set; } = string.Empty;
/// <summary>
/// Country of incorporation
/// </summary>
[Comment("Country code - ISO 3166-1 alpha-2")]
public string Country { get; set; } = string.Empty;
[Comment("Main phone number")]
public string Phone { get; set; } = string.Empty;
/// <summary>
/// Primary contact email for the company
/// </summary>
public string Email { get; set; } = string.Empty;
[Comment("Corporate website URL")]
public string Website { get; set; } = string.Empty;
/// <summary>
/// Tax identification number
/// </summary>
[Comment("EIN or Tax ID - used for compliance")]
public string TaxId { get; set; } = string.Empty;
[Comment("Date company was established")]
public DateTime EstablishedDate { get; set; }
/// <summary>
/// Total headcount across all departments
/// </summary>
public int EmployeeCount { get; set; }
[Comment("Annual revenue in base currency")]
public decimal AnnualRevenue { get; set; }
/// <summary>
/// Currency code for financial transactions
/// </summary>
[Comment("ISO 4217 currency code (USD, EUR, GBP, etc.)")]
public string Currency { get; set; } = string.Empty;
[Comment("IANA timezone identifier")]
public string TimeZone { get; set; } = string.Empty;
/// <summary>
/// Indicates if company is operational
/// </summary>
[Comment("Active status - false for dissolved companies")]
public bool IsActive { get; set; }
[Comment("Record creation timestamp")]
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last modification time
/// </summary>
public DateTime UpdatedAt { get; set; }
[Comment("Username who created this record")]
public string CreatedBy { get; set; } = string.Empty;
/// <summary>
/// Username who last updated this record
/// </summary>
public string UpdatedBy { get; set; } = string.Empty;
/// <summary>
/// All departments belonging to this company
/// </summary>
public ICollection<Department> Departments { get; set; } = new List<Department>();
/// <summary>
/// All projects managed by this company
/// </summary>
public ICollection<Project> Projects { get; set; } = new List<Project>();
}
/// <summary>
/// Organizational unit within a company
/// </summary>
[Comment("Department entity - organizational subdivision with budget and staff")]
public class Department
{
[Comment("Primary key")]
public int Id { get; set; }
/// <summary>
/// Department name
/// </summary>
[Comment("Department display name")]
public string Name { get; set; } = string.Empty;
[Comment("Purpose and responsibilities of department")]
public string Description { get; set; } = string.Empty;
/// <summary>
/// Short code for department
/// </summary>
[Comment("Department code - used in accounting")]
public string Code { get; set; } = string.Empty;
[Comment("Office location or site name")]
public string Location { get; set; } = string.Empty;
/// <summary>
/// Floor number in building
/// </summary>
public string Floor { get; set; } = string.Empty;
[Comment("Building name or number")]
public string Building { get; set; } = string.Empty;
/// <summary>
/// Department phone extension
/// </summary>
public string Phone { get; set; } = string.Empty;
[Comment("Department contact email")]
public string Email { get; set; } = string.Empty;
/// <summary>
/// Annual budget allocation
/// </summary>
[Comment("Budget in company currency")]
public decimal Budget { get; set; }
[Comment("GL account cost center code")]
public string CostCenter { get; set; } = string.Empty;
/// <summary>
/// Whether department is currently active
/// </summary>
public bool IsActive { get; set; }
[Comment("Record creation date")]
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last update timestamp
/// </summary>
public DateTime UpdatedAt { get; set; }
[Comment("Additional notes or comments")]
public string Notes { get; set; } = string.Empty;
/// <summary>
/// Foreign key to parent company
/// </summary>
[Comment("FK to Companies")]
public int CompanyId { get; set; }
/// <summary>
/// Navigation to parent company
/// </summary>
public Company Company { get; set; } = null!;
/// <summary>
/// All employees in this department
/// </summary>
public ICollection<User> Employees { get; set; } = new List<User>();
}
/// <summary>
/// System user with authentication and profile information
/// </summary>
[Comment("User entity - authentication and employee profile data")]
public class User
{
[Comment("Primary key - unique user ID")]
public int Id { get; set; }
/// <summary>
/// User's first name
/// </summary>
[Comment("Given name")]
public string FirstName { get; set; } = string.Empty;
[Comment("Family name or surname")]
public string LastName { get; set; } = string.Empty;
/// <summary>
/// Middle name or initial
/// </summary>
public string MiddleName { get; set; } = string.Empty;
[Comment("Primary email - used for login")]
public string Email { get; set; } = string.Empty;
/// <summary>
/// Unique username for authentication
/// </summary>
[Comment("Login username - must be unique")]
public string Username { get; set; } = string.Empty;
[Comment("Bcrypt hashed password")]
public string PasswordHash { get; set; } = string.Empty;
/// <summary>
/// Salt used for password hashing
/// </summary>
public string Salt { get; set; } = string.Empty;
[Comment("Office phone number")]
public string Phone { get; set; } = string.Empty;
/// <summary>
/// Mobile phone for SMS and 2FA
/// </summary>
[Comment("Mobile number for notifications")]
public string MobilePhone { get; set; } = string.Empty;
[Comment("Job title or position")]
public string JobTitle { get; set; } = string.Empty;
/// <summary>
/// Internal employee identification number
/// </summary>
[Comment("Employee ID badge number")]
public string EmployeeId { get; set; } = string.Empty;
[Comment("Date of birth - for age verification")]
public DateTime? DateOfBirth { get; set; }
/// <summary>
/// Employment start date
/// </summary>
[Comment("Date employee was hired")]
public DateTime HireDate { get; set; }
[Comment("Date employment ended - null if active")]
public DateTime? TerminationDate { get; set; }
/// <summary>
/// Annual salary amount
/// </summary>
[Comment("Salary in specified currency")]
public decimal Salary { get; set; }
[Comment("Salary currency code")]
public string Currency { get; set; } = string.Empty;
/// <summary>
/// Home street address
/// </summary>
public string Address { get; set; } = string.Empty;
[Comment("City of residence")]
public string City { get; set; } = string.Empty;
/// <summary>
/// State or province
/// </summary>
public string State { get; set; } = string.Empty;
[Comment("ZIP or postal code")]
public string PostalCode { get; set; } = string.Empty;
/// <summary>
/// Country of residence
/// </summary>
[Comment("Country code")]
public string Country { get; set; } = string.Empty;
[Comment("Emergency contact name")]
public string EmergencyContactName { get; set; } = string.Empty;
/// <summary>
/// Emergency contact phone
/// </summary>
[Comment("Emergency contact phone number")]
public string EmergencyContactPhone { get; set; } = string.Empty;
[Comment("Comma-separated skills list")]
public string Skills { get; set; } = string.Empty;
/// <summary>
/// User biography or description
/// </summary>
public string Bio { get; set; } = string.Empty;
[Comment("Avatar image URL")]
public string ProfileImageUrl { get; set; } = string.Empty;
/// <summary>
/// User's preferred timezone
/// </summary>
[Comment("IANA timezone identifier")]
public string TimeZone { get; set; } = string.Empty;
[Comment("Preferred UI language code")]
public string Language { get; set; } = string.Empty;
/// <summary>
/// Whether user account is active
/// </summary>
[Comment("Account active flag")]
public bool IsActive { get; set; }
[Comment("Email verified status")]
public bool IsEmailVerified { get; set; }
/// <summary>
/// Phone number verification status
/// </summary>
public bool IsPhoneVerified { get; set; }
[Comment("Last successful login timestamp")]
public DateTime LastLoginAt { get; set; }
/// <summary>
/// IP address of last login
/// </summary>
[Comment("Last login IP address")]
public string LastLoginIp { get; set; } = string.Empty;
[Comment("Failed login attempt counter")]
public int LoginAttempts { get; set; }
/// <summary>
/// Account lockout expiration
/// </summary>
[Comment("Lockout end time - null if not locked")]
public DateTime? LockedUntil { get; set; }
[Comment("Record created timestamp")]
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last profile update time
/// </summary>
public DateTime UpdatedAt { get; set; }
/// <summary>
/// Foreign key to department
/// </summary>
[Comment("FK to Departments")]
public int? DepartmentId { get; set; }
/// <summary>
/// Navigation to department
/// </summary>
public Department? Department { get; set; }
/// <summary>
/// Project assignments for this user
/// </summary>
public ICollection<UserProject> UserProjects { get; set; } = new List<UserProject>();
/// <summary>
/// Projects where user is manager
/// </summary>
public ICollection<Project> ManagedProjects { get; set; } = new List<Project>();
/// <summary>
/// Tasks assigned to this user
/// </summary>
public ICollection<Task> AssignedTasks { get; set; } = new List<Task>();
/// <summary>
/// Tasks created by this user
/// </summary>
public ICollection<Task> CreatedTasks { get; set; } = new List<Task>();
/// <summary>
/// Documents uploaded by user
/// </summary>
public ICollection<Document> UploadedDocuments { get; set; } = new List<Document>();
/// <summary>
/// Comments authored by user
/// </summary>
public ICollection<Comment> Comments { get; set; } = new List<Comment>();
/// <summary>
/// Attachments uploaded by user
/// </summary>
public ICollection<Attachment> UploadedAttachments { get; set; } = new List<Attachment>();
/// <summary>
/// Audit trail entries for user actions
/// </summary>
public ICollection<AuditLog> AuditLogs { get; set; } = new List<AuditLog>();
}
/// <summary>
/// Project tracking entity with budget and timeline
/// </summary>
[Comment("Project entity - tracks initiatives with budget, timeline, and deliverables")]
public class Project
{
[Comment("Primary key")]
public int Id { get; set; }
/// <summary>
/// Project display name
/// </summary>
[Comment("Project name")]
public string Name { get; set; } = string.Empty;
[Comment("Detailed project description")]
public string Description { get; set; } = string.Empty;
/// <summary>
/// Short project code
/// </summary>
[Comment("Project code - used in tracking")]
public string Code { get; set; } = string.Empty;
[Comment("Priority level - High, Medium, Low")]
public string Priority { get; set; } = string.Empty;
/// <summary>
/// Current project status
/// </summary>
[Comment("Status - Planning, Active, On Hold, Completed, Cancelled")]
public string Status { get; set; } = string.Empty;
[Comment("Current project phase")]
public string Phase { get; set; } = string.Empty;
/// <summary>
/// Approved budget amount
/// </summary>
[Comment("Total budget allocation")]
public decimal Budget { get; set; }
[Comment("Budget currency code")]
public string Currency { get; set; } = string.Empty;
/// <summary>
/// Actual money spent
/// </summary>
[Comment("Actual costs incurred")]
public decimal ActualCost { get; set; }
[Comment("Planned start date")]
public DateTime StartDate { get; set; }
/// <summary>
/// Planned end date
/// </summary>
[Comment("Target completion date")]
public DateTime? EndDate { get; set; }
[Comment("Actual completion date")]
public DateTime? ActualEndDate { get; set; }
/// <summary>
/// Estimated hours to complete
/// </summary>
[Comment("Estimated effort in hours")]
public int EstimatedHours { get; set; }
[Comment("Actual hours spent")]
public int ActualHours { get; set; }
/// <summary>
/// Completion percentage (0-100)
/// </summary>
[Comment("Percent complete - 0 to 100")]
public decimal PercentComplete { get; set; }
[Comment("Risk assessment - Low, Medium, High, Critical")]
public string RiskLevel { get; set; } = string.Empty;
/// <summary>
/// Overall project health
/// </summary>
[Comment("Health status - On Track, At Risk, Off Track")]
public string HealthStatus { get; set; } = string.Empty;
[Comment("Development methodology - Agile, Waterfall, etc.")]
public string Methodology { get; set; } = string.Empty;
/// <summary>
/// Source control repository URL
/// </summary>
[Comment("Git repository URL")]
public string Repository { get; set; } = string.Empty;
[Comment("Documentation wiki or site URL")]
public string DocumentationUrl { get; set; } = string.Empty;
/// <summary>
/// Whether project is active
/// </summary>
[Comment("Active status flag")]
public bool IsActive { get; set; }
[Comment("Public visibility flag")]
public bool IsPublic { get; set; }
/// <summary>
/// Project creation timestamp
/// </summary>
public DateTime CreatedAt { get; set; }
[Comment("Last update timestamp")]
public DateTime UpdatedAt { get; set; }
/// <summary>
/// Additional project notes
/// </summary>
public string Notes { get; set; } = string.Empty;
/// <summary>
/// Foreign key to company
/// </summary>
[Comment("FK to Companies")]
public int CompanyId { get; set; }
/// <summary>
/// Foreign key to project manager
/// </summary>
[Comment("FK to Users - project manager")]
public int? ProjectManagerId { get; set; }
/// <summary>
/// Navigation to company
/// </summary>
public Company Company { get; set; } = null!;
/// <summary>
/// Navigation to project manager
/// </summary>
public User? ProjectManager { get; set; }
/// <summary>
/// Team members assigned to project
/// </summary>
public ICollection<UserProject> UserProjects { get; set; } = new List<UserProject>();
/// <summary>
/// All tasks in this project
/// </summary>
public ICollection<Task> Tasks { get; set; } = new List<Task>();
/// <summary>
/// Documents related to project
/// </summary>
public ICollection<Document> Documents { get; set; } = new List<Document>();
}
/// <summary>
/// Work item or task within a project
/// </summary>
[Comment("Task entity - individual work items with assignments and tracking")]
public class Task
{
[Comment("Primary key")]
public int Id { get; set; }
/// <summary>
/// Task title or summary
/// </summary>
[Comment("Task title")]
public string Title { get; set; } = string.Empty;
[Comment("Detailed task description")]
public string Description { get; set; } = string.Empty;
/// <summary>
/// Current task status
/// </summary>
[Comment("Status - New, In Progress, Review, Done, Cancelled")]
public string Status { get; set; } = string.Empty;
[Comment("Priority - Critical, High, Medium, Low")]
public string Priority { get; set; } = string.Empty;
/// <summary>
/// Task type classification
/// </summary>
[Comment("Type - Bug, Feature, Enhancement, Research")]
public string Type { get; set; } = string.Empty;
[Comment("Category for grouping tasks")]
public string Category { get; set; } = string.Empty;
/// <summary>
/// Estimated hours to complete
/// </summary>
[Comment("Time estimate in hours")]
public int EstimatedHours { get; set; }
[Comment("Actual time spent in hours")]
public int ActualHours { get; set; }
/// <summary>
/// Story points for agile estimation
/// </summary>
[Comment("Agile story points")]
public int StoryPoints { get; set; }
[Comment("Completion percentage - 0 to 100")]
public decimal PercentComplete { get; set; }
/// <summary>
/// Work start date
/// </summary>
[Comment("Task start date")]
public DateTime? StartDate { get; set; }
[Comment("Target due date")]
public DateTime? DueDate { get; set; }
/// <summary>
/// Actual completion date
/// </summary>
[Comment("Date task was completed")]
public DateTime? CompletedDate { get; set; }
[Comment("Resolution notes")]
public string Resolution { get; set; } = string.Empty;
/// <summary>
/// Definition of done criteria
/// </summary>
[Comment("Acceptance criteria for completion")]
public string AcceptanceCriteria { get; set; } = string.Empty;
[Comment("Testing notes and results")]
public string TestNotes { get; set; } = string.Empty;
/// <summary>
/// Git branch name for this task
/// </summary>
[Comment("Feature branch name")]
public string Branch { get; set; } = string.Empty;
[Comment("Pull request URL")]
public string PullRequestUrl { get; set; } = string.Empty;
/// <summary>
/// Whether task is blocked
/// </summary>
[Comment("Blocked status flag")]
public bool IsBlocked { get; set; }
[Comment("Reason task is blocked")]
public string BlockedReason { get; set; } = string.Empty;
/// <summary>
/// Whether time is billable to client
/// </summary>
[Comment("Billable flag for time tracking")]
public bool IsBillable { get; set; }
[Comment("Task creation timestamp")]
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last update timestamp
/// </summary>
public DateTime UpdatedAt { get; set; }
/// <summary>
/// Foreign key to project
/// </summary>
[Comment("FK to Projects")]
public int ProjectId { get; set; }
/// <summary>
/// Foreign key to assigned user
/// </summary>
[Comment("FK to Users - assignee")]
public int? AssignedToId { get; set; }
/// <summary>
/// Foreign key to creator
/// </summary>
[Comment("FK to Users - creator")]
public int CreatedById { get; set; }
/// <summary>
/// Navigation to project
/// </summary>
public Project Project { get; set; } = null!;
/// <summary>
/// Navigation to assigned user
/// </summary>
public User? AssignedTo { get; set; }
/// <summary>
/// Navigation to creator
/// </summary>
public User CreatedBy { get; set; } = null!;
/// <summary>
/// Comments on this task
/// </summary>
public ICollection<Comment> Comments { get; set; } = new List<Comment>();
/// <summary>
/// Tags applied to task
/// </summary>
public ICollection<TaskTag> TaskTags { get; set; } = new List<TaskTag>();
}
/// <summary>
/// Document or file attached to project
/// </summary>
[Comment("Document entity - file storage with versioning and access control")]
public class Document
{
[Comment("Primary key")]
public int Id { get; set; }
/// <summary>
/// Display name for document
/// </summary>
[Comment("Document display name")]
public string Name { get; set; } = string.Empty;
[Comment("Original uploaded filename")]
public string OriginalName { get; set; } = string.Empty;
/// <summary>
/// Document description
/// </summary>
[Comment("Document description or summary")]
public string Description { get; set; } = string.Empty;
[Comment("Category - Specification, Design, Report, etc.")]
public string Category { get; set; } = string.Empty;
/// <summary>
/// Document type
/// </summary>
[Comment("Document type classification")]
public string Type { get; set; } = string.Empty;
[Comment("Storage path or S3 key")]
public string FilePath { get; set; } = string.Empty;
/// <summary>
/// MIME content type
/// </summary>
[Comment("MIME type - application/pdf, image/png, etc.")]
public string MimeType { get; set; } = string.Empty;
[Comment("File size in bytes")]
public long FileSize { get; set; }
/// <summary>
/// File hash for integrity
/// </summary>
[Comment("SHA256 hash for integrity verification")]
public string Hash { get; set; } = string.Empty;
[Comment("Version number")]
public string Version { get; set; } = string.Empty;
/// <summary>
/// Whether this is latest version
/// </summary>
[Comment("Latest version flag")]
public bool IsLatestVersion { get; set; }
[Comment("Document status - Draft, Review, Approved, Archived")]
public string Status { get; set; } = string.Empty;
/// <summary>
/// Access control level
/// </summary>
[Comment("Access level - Public, Internal, Confidential, Restricted")]
public string AccessLevel { get; set; } = string.Empty;
[Comment("Document expiration date")]
public DateTime? ExpiryDate { get; set; }
/// <summary>
/// Download counter
/// </summary>
[Comment("Total download count")]
public int Downloads { get; set; }
[Comment("Encryption status flag")]
public bool IsEncrypted { get; set; }
/// <summary>
/// Searchable keywords
/// </summary>
[Comment("Comma-separated keywords")]
public string Keywords { get; set; } = string.Empty;
[Comment("Upload timestamp")]
public DateTime CreatedAt { get; set; }
/// <summary>
/// Last modification time
/// </summary>
public DateTime UpdatedAt { get; set; }
/// <summary>
/// Foreign key to project
/// </summary>
[Comment("FK to Projects")]
public int ProjectId { get; set; }
/// <summary>
/// Foreign key to uploader
/// </summary>
[Comment("FK to Users - uploader")]
public int UploadedById { get; set; }
/// <summary>
/// Navigation to project
/// </summary>
public Project Project { get; set; } = null!;
/// <summary>
/// Navigation to uploader
/// </summary>
public User UploadedBy { get; set; } = null!;
}
/// <summary>
/// Comment or note on a task
/// </summary>
[Comment("Comment entity - discussion threads on tasks")]
public class Comment
{
[Comment("Primary key")]
public int Id { get; set; }
/// <summary>
/// Comment text content
/// </summary>
[Comment("Comment plain text content")]
public string Content { get; set; } = string.Empty;
[Comment("HTML formatted content")]
public string FormattedContent { get; set; } = string.Empty;
/// <summary>
/// Comment type
/// </summary>
[Comment("Type - Comment, Note, System")]
public string Type { get; set; } = string.Empty;
[Comment("Internal visibility flag")]
public bool IsInternal { get; set; }