docs: add data model reference with entity relationship diagram (DOC-08)#917
docs: add data model reference with entity relationship diagram (DOC-08)#917Chris0Jeky merged 3 commits intomainfrom
Conversation
Comprehensive reference covering all 30+ domain entities, their fields, types, constraints, and relationships. Includes Mermaid ERD diagram for core entities and relationship summary table. Closes #875
Self-review: adversarial checkEntity coverageVerified all 37 entity files in
Field accuracy spot-checks
Mermaid ERD
Relationship completeness
Cross-links
No issues found. LGTM. |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive Data Model Reference document and updates existing API documentation to link to it. The new documentation details the system's entities, constraints, and relationships using Mermaid diagrams and descriptive tables. Review feedback identifies opportunities to improve the accuracy and completeness of the entity-relationship diagram and the relationship summary table, specifically by explicitly linking the User entity to several domain entities such as AbuseEvent, CardComment, and AutomationProposal.
| User ||--o{ Board : "owns" | ||
| User ||--o{ BoardAccess : "has access" | ||
| User ||--o{ ApiKey : "authenticates with" | ||
| User ||--o{ ExternalLogin : "linked to" | ||
| User ||--o| MfaCredential : "has" | ||
| User ||--o| UserPreference : "has" | ||
| User ||--o| NotificationPreference : "has" | ||
| User ||--o{ Notification : "receives" | ||
| User ||--o{ ChatSession : "creates" | ||
| User ||--o{ LlmRequest : "submits" | ||
| User ||--o{ LlmUsageRecord : "tracked for" | ||
| User ||--o{ AuditLog : "triggers" | ||
| User ||--o{ IntegrationConnector : "owns" | ||
| User ||--o{ KnowledgeDocument : "owns" | ||
| User ||--o| AbuseActor : "tracked as" | ||
| User ||--o{ AgentProfile : "owns" |
There was a problem hiding this comment.
The Mermaid ERD is missing several direct relationships between the User entity and other domain entities that are explicitly linked via foreign keys in the code. For completeness, consider adding links for CardComment, AutomationProposal, ArchiveItem, AgentRun, OutboundWebhookSubscription, and CommandRun.
User ||--o{ Board : "owns"
User ||--o{ BoardAccess : "has access"
User ||--o{ ApiKey : "authenticates with"
User ||--o{ ExternalLogin : "linked to"
User ||--o| MfaCredential : "has"
User ||--o| UserPreference : "has"
User ||--o| NotificationPreference : "has"
User ||--o{ Notification : "receives"
User ||--o{ ChatSession : "creates"
User ||--o{ LlmRequest : "submits"
User ||--o{ LlmUsageRecord : "tracked for"
User ||--o{ AuditLog : "triggers"
User ||--o{ IntegrationConnector : "owns"
User ||--o{ KnowledgeDocument : "owns"
User ||--o| AbuseActor : "tracked as"
User ||--o{ AgentProfile : "owns"
User ||--o{ CardComment : "authors"
User ||--o{ AutomationProposal : "requests"
User ||--o{ ArchiveItem : "archived by"
User ||--o{ AgentRun : "triggers"
User ||--o{ OutboundWebhookSubscription : "manages"
User ||--o{ CommandRun : "initiates"|
|
||
| OutboundWebhookSubscription ||--o{ OutboundWebhookDelivery : "delivers" | ||
|
|
||
| AbuseActor ||--o{ AbuseEvent : "records" |
There was a problem hiding this comment.
In the domain model (AbuseEvent.cs), AbuseEvent links to User via ActorUserId, not directly to the AbuseActor entity. While AbuseActor is 1:1 with User, the ERD should ideally reflect the actual foreign key relationship to the User table.
| AbuseActor ||--o{ AbuseEvent : "records" | |
| User ||--o{ AbuseEvent : "triggers" |
| | AgentProfile -> AgentRun | One-to-many | A profile executes many runs | | ||
| | AgentRun -> AgentRunEvent | One-to-many | A run emits many events | | ||
| | User -> AbuseActor | One-to-zero-or-one | One abuse tracking record per user | | ||
| | AbuseActor -> AbuseEvent | One-to-many (implicit via ActorUserId) | Abuse events log state transitions | |
There was a problem hiding this comment.
In the schema (AbuseEvent.cs), AbuseEvent links to User via ActorUserId, not directly to AbuseActor. The summary should reflect the actual foreign key relationship.
| | AbuseActor -> AbuseEvent | One-to-many (implicit via ActorUserId) | Abuse events log state transitions | | |
| | User -> AbuseEvent | One-to-many | Abuse events log state transitions | |
| | AbuseActor -> AbuseEvent | One-to-many (implicit via ActorUserId) | Abuse events log state transitions | | ||
| | Board -> ArchiveItem | One-to-many | Archived snapshots scoped to a board | | ||
| | CommandRun -> CommandRunLog | One-to-many | Execution logs per command run | | ||
| | Board -> KnowledgeDocument | One-to-many (optional) | Documents optionally scoped to a board | |
There was a problem hiding this comment.
The Relationship Summary table is missing several entries for entities that link back to the User entity, as well as the AuditLog entity which is shown in the diagram but omitted here.
| | Board -> KnowledgeDocument | One-to-many (optional) | Documents optionally scoped to a board | | |
| | Board -> KnowledgeDocument | One-to-many (optional) | Documents optionally scoped to a board | | |
| | User -> CardComment | One-to-many | A user authors many comments | | |
| | User -> AutomationProposal | One-to-many | A user requests many proposals | | |
| | User -> ArchiveItem | One-to-many | A user archives many items | | |
| | User -> AgentRun | One-to-many | A user triggers many agent runs | | |
| | User -> OutboundWebhookSubscription | One-to-many | A user manages many webhook subscriptions | | |
| | User -> CommandRun | One-to-many | A user initiates many command runs | | |
| | User -> AuditLog | One-to-many | A user triggers many audit log entries | |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf04b805bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| |-------|------|----------|-------------|-------------| | ||
| | Id | `Guid` | Yes | PK | | | ||
| | Name | `string` | Yes | 1-100 chars | Board display name | | ||
| | Description | `string?` | No | Max 1000 chars | Optional description | |
There was a problem hiding this comment.
Correct Board.Description max length in reference
This row documents Board.Description as Max 1000 chars, but the persisted schema currently caps it at 500 via BoardConfiguration.Configure (builder.Property(b => b.Description).HasMaxLength(500)), so readers following this doc can submit values that pass domain checks but fail at persistence time. Since this file is positioned as a data model/constraint reference, the limit should match the effective database constraint.
Useful? React with 👍 / 👎.
| | Id | `Guid` | Yes | PK | | | ||
| | SourceType | `ProposalSourceType` | Yes | Enum: Queue, Chat, Manual | Origin of proposal | | ||
| | SourceReferenceId | `string?` | No | | External reference | | ||
| | BoardId | `Guid?` | No | FK to Board | Target board | |
There was a problem hiding this comment.
Remove incorrect FK claim for AutomationProposal.BoardId
The table marks AutomationProposal.BoardId as FK to Board, but the EF model does not define that foreign key (AutomationProposalConfiguration.Configure only configures the property/indexes and no HasOne(...).HasForeignKey(...) exists, and the model snapshot shows no FK from AutomationProposals.BoardId). Documenting it as an enforced FK can mislead migration/query assumptions and relationship reasoning.
Useful? React with 👍 / 👎.
Adversarial Review -- PR #917 (Data Model Reference)I cross-checked every entity section against the actual source code in Critical: Incorrect FK claimsThe doc marks many Fields falsely documented as FKs (no
Fields correctly documented as FKs (actual FK constraint exists):
Fix: Change "FK to X" to "references X (no FK constraint)" for all non-FK fields. This is the single most important fix for accuracy. Critical: AbuseActor and AbuseEvent are not persistedThere is no Fix: Add a note that these are domain-only entities not yet mapped to the database, or move them to a separate section. High: Board.Description max length (Codex bot confirmed)The domain entity allows 1000 chars but the EF config sets Fix: Update to "Max 500 chars (DB); domain allows 1000". Medium: Missing ERD relationships (where real FKs exist)The ERD is missing two relationships backed by actual FK constraints:
The Relationship Summary table is also missing:
Medium: ERD shows non-existent DB relationshipsSeveral ERD lines imply DB relationships that don't exist as FK constraints:
These are logical/domain relationships only. The ERD should distinguish between enforced FK relationships and logical associations, or add a legend. Low: Gemini bot suggestions -- partial validity
I will now fix these issues in the doc. |
…ntities - Fix Board.Description max length: DB constraint is 500, not 1000 - Remove false FK claims on AutomationProposal.BoardId, AutomationProposal.RequestedByUserId, LlmUsageRecord.UserId, AgentProfile.UserId, KnowledgeDocument.UserId/BoardId (no FK constraints exist in EF Core configuration) - Add missing ERD relationships where real FKs exist: User->CardComment, User->OutboundWebhookSubscription, Board->LlmRequest - Mark AbuseActor and AbuseEvent as domain-only (no DbSet, no EF config, no database table) - Add FK vs logical legend to ERD and Relationship Summary table - Add FK/Logical column to Relationship Summary with cascade behavior - Note UserPreference enums stored as strings (not integers) - Add Persistence Notes about FK vs logical references
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c93d2eae0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | Relationship | Type | FK/Logical | Description | | ||
| |---|---|---|---| | ||
| | User -> Board | One-to-many | FK (SetNull) | A user can own many boards (via `OwnerId`) | | ||
| | User -> BoardAccess | One-to-many | FK (Cascade) | A user can have access to many boards | |
There was a problem hiding this comment.
Mark User->BoardAccess delete rule as Restrict
This row documents User -> BoardAccess as FK (Cascade), but the actual EF mapping uses DeleteBehavior.Restrict on BoardAccess.UserId (BoardAccessConfiguration.Configure, HasForeignKey(ba => ba.UserId).OnDelete(DeleteBehavior.Restrict)). Keeping this as cascade misstates real delete semantics and can lead maintainers to design cleanup/migration flows that assume user deletion will automatically remove board access rows.
Useful? React with 👍 / 👎.
| | Board -> AutomationProposal | One-to-many | Logical | Proposals target boards | | ||
| | Board -> ArchiveItem | One-to-many | Logical | Archived snapshots scoped to a board | | ||
| | Board -> KnowledgeDocument | One-to-many (optional) | Logical | Documents optionally scoped to a board | | ||
| | Column -> Card | One-to-many | FK (Cascade) | A column holds many cards | |
There was a problem hiding this comment.
Document Column->Card FK delete behavior as Restrict
The relationship table says Column -> Card is FK (Cascade), but ColumnConfiguration.Configure defines .HasForeignKey(card => card.ColumnId).OnDelete(DeleteBehavior.Restrict). This mismatch is important because it changes deletion expectations: readers may think deleting a column cascades card deletion when the configured model actually restricts that operation.
Useful? React with 👍 / 👎.
Summary
docs/architecture/DATA_MODEL.mddocumenting all 30+ domain entities with field-level detail (types, constraints, required/optional)Closes #875
Test plan
backend/src/Taskdeck.Domain/Entities/are missing from the reference