|
| 1 | +# Interface Graph Inventory for WindowsAppCommunity.Sdk |
| 2 | + |
| 3 | +This document provides a comprehensive inventory of the interface hierarchy for the three main entities in the WindowsAppCommunity.Sdk: **Publisher**, **Project**, and **User**. This mapping is intended to help with blog generator development by clearly defining the type relationships and data access patterns. |
| 4 | + |
| 5 | +## Core Entity Interfaces |
| 6 | + |
| 7 | +### IReadOnlyUser |
| 8 | +``` |
| 9 | +IReadOnlyUser : IReadOnlyEntity, IReadOnlyPublisherRoleCollection, IReadOnlyProjectRoleCollection, IHasId |
| 10 | +``` |
| 11 | + |
| 12 | +**Purpose**: Represents a user with access to their entity data, publisher roles, and project roles. |
| 13 | + |
| 14 | +**Key Properties**: |
| 15 | +- Inherits all properties from `IReadOnlyEntity` (name, description, connections, links, images) |
| 16 | +- Access to publisher roles via `IReadOnlyPublisherRoleCollection` |
| 17 | +- Access to project roles via `IReadOnlyProjectRoleCollection` |
| 18 | + |
| 19 | +### IReadOnlyPublisher |
| 20 | +``` |
| 21 | +IReadOnlyPublisher : IReadOnlyPublisher<IReadOnlyPublisherRoleCollection> |
| 22 | +
|
| 23 | +IReadOnlyPublisher<TPublisherCollection> : IReadOnlyEntity, IReadOnlyAccentColor, IReadOnlyUserRoleCollection, IReadOnlyProjectCollection, IHasId |
| 24 | + where TPublisherCollection : IReadOnlyPublisherCollection<IReadOnlyPublisherRole> |
| 25 | +``` |
| 26 | + |
| 27 | +**Purpose**: Represents a publisher entity with accent color, user roles, projects, and hierarchical publisher relationships. |
| 28 | + |
| 29 | +**Key Properties**: |
| 30 | +- Inherits all properties from `IReadOnlyEntity` (name, description, connections, links, images) |
| 31 | +- `AccentColor` via `IReadOnlyAccentColor` |
| 32 | +- User roles via `IReadOnlyUserRoleCollection` |
| 33 | +- Projects via `IReadOnlyProjectCollection` |
| 34 | +- `ParentPublishers` and `ChildPublishers` (hierarchical relationships) |
| 35 | + |
| 36 | +### IReadOnlyProject |
| 37 | +``` |
| 38 | +IReadOnlyProject : IReadOnlyProject<IReadOnlyProjectCollection> |
| 39 | +
|
| 40 | +IReadOnlyProject<TDependencyCollection> : IReadOnlyEntity, IReadOnlyImagesCollection, IReadOnlyUserRoleCollection, IReadOnlyAccentColor, IReadOnlyFeaturesCollection, IHasId |
| 41 | + where TDependencyCollection : IReadOnlyProjectCollection<IReadOnlyProject> |
| 42 | +``` |
| 43 | + |
| 44 | +**Purpose**: Represents a project entity with dependencies, features, accent color, users, and images. |
| 45 | + |
| 46 | +**Key Properties**: |
| 47 | +- Inherits all properties from `IReadOnlyEntity` (name, description, connections, links, images) |
| 48 | +- Additional images via `IReadOnlyImagesCollection` |
| 49 | +- User roles via `IReadOnlyUserRoleCollection` |
| 50 | +- `AccentColor` via `IReadOnlyAccentColor` |
| 51 | +- `Features` via `IReadOnlyFeaturesCollection` |
| 52 | +- `Dependencies` (other projects this project depends on) |
| 53 | +- `Category` (string property for app store categorization) |
| 54 | +- `GetPublisherAsync()` method to retrieve associated publisher |
| 55 | + |
| 56 | +## Supporting Interface Hierarchy |
| 57 | + |
| 58 | +### Base Entity Interface |
| 59 | +``` |
| 60 | +IReadOnlyEntity : IReadOnlyConnectionsCollection, IReadOnlyLinksCollection, IReadOnlyImagesCollection, IHasId |
| 61 | +``` |
| 62 | + |
| 63 | +**Properties**: |
| 64 | +- `Name` (string) |
| 65 | +- `Description` (string, supports markdown) |
| 66 | +- `ExtendedDescription` (string, supports markdown) |
| 67 | +- `ForgetMe` (bool?) |
| 68 | +- `IsUnlisted` (bool) |
| 69 | + |
| 70 | +**Events**: |
| 71 | +- `NameUpdated` |
| 72 | +- `DescriptionUpdated` |
| 73 | +- `ExtendedDescriptionUpdated` |
| 74 | +- `ForgetMeUpdated` |
| 75 | +- `IsUnlistedUpdated` |
| 76 | + |
| 77 | +### Collection Interfaces |
| 78 | + |
| 79 | +#### IReadOnlyConnectionsCollection |
| 80 | +``` |
| 81 | +IReadOnlyConnectionsCollection : IHasId |
| 82 | +``` |
| 83 | +- `GetConnectionsAsync()` → `IAsyncEnumerable<IReadOnlyConnection>` |
| 84 | +- Events: `ConnectionsAdded`, `ConnectionsRemoved` |
| 85 | + |
| 86 | +#### IReadOnlyLinksCollection |
| 87 | +``` |
| 88 | +IReadOnlyLinksCollection : IHasId |
| 89 | +``` |
| 90 | +- `Links` (Link[] property) |
| 91 | +- Events: `LinksAdded`, `LinksRemoved` |
| 92 | + |
| 93 | +#### IReadOnlyImagesCollection |
| 94 | +``` |
| 95 | +IReadOnlyImagesCollection : IHasId |
| 96 | +``` |
| 97 | +- `GetImageFilesAsync()` → `IAsyncEnumerable<IFile>` |
| 98 | +- Events: `ImagesAdded`, `ImagesRemoved` |
| 99 | + |
| 100 | +#### IReadOnlyAccentColor |
| 101 | +``` |
| 102 | +IReadOnlyAccentColor : IHasId |
| 103 | +``` |
| 104 | +- `AccentColor` (string?) |
| 105 | +- Events: `AccentColorUpdated` |
| 106 | + |
| 107 | +#### IReadOnlyFeaturesCollection |
| 108 | +``` |
| 109 | +IReadOnlyFeaturesCollection : IHasId |
| 110 | +``` |
| 111 | +- `Features` (string[]) |
| 112 | +- Events: `FeaturesAdded`, `FeaturesRemoved` |
| 113 | + |
| 114 | +### Role-Based Collections |
| 115 | + |
| 116 | +#### IReadOnlyUserRoleCollection |
| 117 | +``` |
| 118 | +IReadOnlyUserRoleCollection : IReadOnlyUserCollection<IReadOnlyUserRole> |
| 119 | +IReadOnlyUserCollection<TUser> : IHasId where TUser : IReadOnlyUser |
| 120 | +``` |
| 121 | +- `GetUsersAsync()` → `IAsyncEnumerable<TUser>` |
| 122 | + |
| 123 | +#### IReadOnlyProjectRoleCollection |
| 124 | +``` |
| 125 | +IReadOnlyProjectRoleCollection : IReadOnlyProjectCollection<IReadOnlyProjectRole> |
| 126 | +``` |
| 127 | + |
| 128 | +#### IReadOnlyPublisherRoleCollection |
| 129 | +``` |
| 130 | +IReadOnlyPublisherRoleCollection : IReadOnlyPublisherCollection<IReadOnlyPublisherRole> |
| 131 | +``` |
| 132 | + |
| 133 | +#### IReadOnlyProjectCollection |
| 134 | +``` |
| 135 | +IReadOnlyProjectCollection<TProject> : IHasId where TProject : IReadOnlyProject |
| 136 | +``` |
| 137 | +- `GetProjectsAsync()` → `IAsyncEnumerable<TProject>` |
| 138 | +- Events: `ProjectsAdded`, `ProjectsRemoved` |
| 139 | + |
| 140 | +#### IReadOnlyPublisherCollection |
| 141 | +``` |
| 142 | +IReadOnlyPublisherCollection<TPublisher> : IHasId where TPublisher : IReadOnlyPublisher |
| 143 | +``` |
| 144 | +- `GetPublishersAsync()` → `IAsyncEnumerable<TPublisher>` |
| 145 | +- Events: `PublishersAdded`, `PublishersRemoved` |
| 146 | + |
| 147 | +### Role Interfaces |
| 148 | + |
| 149 | +#### IReadOnlyUserRole |
| 150 | +``` |
| 151 | +IReadOnlyUserRole : IReadOnlyUser |
| 152 | +``` |
| 153 | +- `Role` (Role property) |
| 154 | + |
| 155 | +#### IReadOnlyProjectRole |
| 156 | +``` |
| 157 | +IReadOnlyProjectRole : IReadOnlyProject |
| 158 | +``` |
| 159 | +- `Role` (Role property) |
| 160 | + |
| 161 | +#### IReadOnlyPublisherRole |
| 162 | +``` |
| 163 | +IReadOnlyPublisherRole : IReadOnlyPublisher |
| 164 | +``` |
| 165 | +- `Role` (Role property) |
| 166 | + |
| 167 | +## Supporting Data Classes |
| 168 | + |
| 169 | +### Role |
| 170 | +```csharp |
| 171 | +public class Role |
| 172 | +{ |
| 173 | + public required string Id { get; init; } |
| 174 | + public required string Name { get; init; } |
| 175 | + public required string Description { get; init; } |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +### Link |
| 180 | +```csharp |
| 181 | +public class Link : IStorable |
| 182 | +{ |
| 183 | + public required string Id { get; init; } |
| 184 | + public required string Url { get; set; } |
| 185 | + public required string Name { get; set; } |
| 186 | + public required string Description { get; set; } |
| 187 | +} |
| 188 | +``` |
| 189 | + |
| 190 | +### IReadOnlyConnection |
| 191 | +```csharp |
| 192 | +public interface IReadOnlyConnection |
| 193 | +{ |
| 194 | + string Id { get; } |
| 195 | + Task<string> GetValueAsync(CancellationToken cancellationToken = default); |
| 196 | + event EventHandler<string>? ValueUpdated; |
| 197 | +} |
| 198 | +``` |
| 199 | + |
| 200 | +## Data Access Patterns for Blog Generator |
| 201 | + |
| 202 | +### For User Profiles |
| 203 | +1. **Basic Info**: `IReadOnlyEntity` → name, description, extendedDescription |
| 204 | +2. **Visual Elements**: `IReadOnlyImagesCollection` → profile images |
| 205 | +3. **External Links**: `IReadOnlyLinksCollection` → social/external profiles |
| 206 | +4. **App Connections**: `IReadOnlyConnectionsCollection` → connected applications |
| 207 | +5. **Project Involvement**: `IReadOnlyProjectRoleCollection` → projects and roles |
| 208 | +6. **Publisher Involvement**: `IReadOnlyPublisherRoleCollection` → publishers and roles |
| 209 | + |
| 210 | +### For Publisher Profiles |
| 211 | +1. **Basic Info**: `IReadOnlyEntity` → name, description, extendedDescription |
| 212 | +2. **Branding**: `IReadOnlyAccentColor` → brand color |
| 213 | +3. **Visual Elements**: `IReadOnlyImagesCollection` → logos, banners |
| 214 | +4. **External Links**: `IReadOnlyLinksCollection` → websites, social media |
| 215 | +5. **App Connections**: `IReadOnlyConnectionsCollection` → connected applications |
| 216 | +6. **Team Members**: `IReadOnlyUserRoleCollection` → users and their roles |
| 217 | +7. **Published Projects**: `IReadOnlyProjectCollection` → all projects under publisher |
| 218 | +8. **Publisher Hierarchy**: `ParentPublishers`, `ChildPublishers` → organizational structure |
| 219 | + |
| 220 | +### For Project Profiles |
| 221 | +1. **Basic Info**: `IReadOnlyEntity` → name, description, extendedDescription |
| 222 | +2. **Categorization**: `Category` → app store category |
| 223 | +3. **Branding**: `IReadOnlyAccentColor` → project theme color |
| 224 | +4. **Visual Elements**: `IReadOnlyImagesCollection` → screenshots, icons |
| 225 | +5. **External Links**: `IReadOnlyLinksCollection` → project website, documentation |
| 226 | +6. **App Connections**: `IReadOnlyConnectionsCollection` → integrations |
| 227 | +7. **Features**: `IReadOnlyFeaturesCollection` → feature list |
| 228 | +8. **Team Members**: `IReadOnlyUserRoleCollection` → contributors and roles |
| 229 | +9. **Dependencies**: `Dependencies` → other projects this depends on |
| 230 | +10. **Publisher**: `GetPublisherAsync()` → owning publisher |
| 231 | + |
| 232 | +## Interface Dependency Graph |
| 233 | + |
| 234 | +``` |
| 235 | +IHasId (base interface with Id property) |
| 236 | +├── IReadOnlyEntity |
| 237 | +│ ├── IReadOnlyConnectionsCollection |
| 238 | +│ ├── IReadOnlyLinksCollection |
| 239 | +│ └── IReadOnlyImagesCollection |
| 240 | +├── IReadOnlyAccentColor |
| 241 | +├── IReadOnlyFeaturesCollection |
| 242 | +├── IReadOnlyUserCollection<T> |
| 243 | +│ └── IReadOnlyUserRoleCollection |
| 244 | +├── IReadOnlyProjectCollection<T> |
| 245 | +│ └── IReadOnlyProjectRoleCollection |
| 246 | +├── IReadOnlyPublisherCollection<T> |
| 247 | +│ └── IReadOnlyPublisherRoleCollection |
| 248 | +├── IReadOnlyUser |
| 249 | +│ └── IReadOnlyUserRole |
| 250 | +├── IReadOnlyProject<T> |
| 251 | +│ └── IReadOnlyProjectRole |
| 252 | +└── IReadOnlyPublisher<T> |
| 253 | + └── IReadOnlyPublisherRole |
| 254 | +``` |
| 255 | + |
| 256 | +## Recommendations for Blog Generator Implementation |
| 257 | + |
| 258 | +1. **Start with Core Entities**: Implement converters for `IReadOnlyUser`, `IReadOnlyPublisher`, and `IReadOnlyProject` first |
| 259 | +2. **Implement Supporting Collections**: Handle each collection interface as a separate template component |
| 260 | +3. **Handle Async Data**: Many collections use `IAsyncEnumerable<T>` - ensure proper async handling in templates |
| 261 | +4. **Link Resolution**: Pre-resolve relationships (like publisher for projects) to avoid async calls in templates |
| 262 | +5. **Role Handling**: Create specialized templates for role-based views vs direct entity views |
| 263 | +6. **Image Processing**: Handle `IFile` objects from `IReadOnlyImagesCollection` for proper image rendering |
| 264 | +7. **Connection Values**: Cache `IReadOnlyConnection.GetValueAsync()` results before template rendering |
| 265 | + |
| 266 | +This interface inventory provides the foundation for systematically implementing blog generation for each entity type while maintaining clear separation of concerns. |
0 commit comments