QuinntyneBrown/slackish-v2
31.2
Weak · 20 September 2026
2.6k
lines of production code
C#
with TypeScript
4
measurements over time
What this system is
Slackish is a multi-tenant real-time chat application built on ASP.NET Web API and Angular. It provides core messaging capabilities via SignalR, allowing users to send and receive messages within teams and conversations. The system manages user profiles, team structures, and authentication through JWT, while supporting soft-deletion and caching for data integrity and performance.
Features
Add Teams API endpoints for managing and switching teams
Introduces a new Teams feature area with a REST API (under /api/teams) and corresponding MediatR handlers to manage team data. Users can now add or update teams, retrieve teams by ID, name, or list all for a tenant, and specifically set or get the current team for a user. The implementation includes soft-deletion for teams and utilizes caching for current team lookups.
Features/Teams · high confidence
Initial Angular client application structure and core UI components
The ClientApp directory has been initialized with a new Angular application structure, establishing the foundational UI and routing for the 'Slackish' product. This includes the main application module, a landing page, and a master page layout that wraps the global header and main content area. The application features a conversations interface with a two-column grid layout (list and detail views), a login page with form handling and authentication logic, and team management pages for discovery and creation. Shared infrastructure includes an authentication guard, HTTP services for API communication (including OAuth token handling), a local storage service, and reusable UI components such as a header, dots menu, and popover.
ClientApp · high confidence
Initial project structure and configuration for Slackish
This change introduces the foundational project structure for the Slackish real-time chat application. It establishes the ASP.NET Web API backend configuration (ApiConfiguration, Startup, Unity DI, Swagger, SignalR, and JWT/OAuth authentication) and sets up the Angular frontend build pipeline via Webpack and TypeScript. It also includes the initial database connection string, client-side routing rules, and the main entry point (index.html).
(repo-wide) · high confidence
Introduce JWT-based authentication and real-time messaging capabilities
This change adds a new security layer and messaging feature set. The Security folder introduces JWT-based authentication, including configuration (AuthConfiguration), token generation and validation (JwtWriterFormat, JwtOptions), and an OAuth provider (OAuthProvider) that validates credentials via IsAuthenticUserQuery and retrieves user claims via GetClaimsForUserQuery. It also includes an EncryptionService for password hashing (SHA256) and string encryption (AES/Rijndael). The Features/Messages folder implements a real-time messaging system using SignalR (MessageHub) and an API controller (MessagesController) with MediatR handlers (GetMessagesQuery, SendMessageAndReplyCommand, SendMessageCommand) to retrieve, send, and broadcast messages within tenant groups.
Features/Messages, Security · high confidence
Introduce user profiles and conversation management APIs
This change adds the foundational API endpoints and backend logic for managing user profiles and conversations. Users can now register new accounts via the POST /api/profiles/register endpoint, retrieve their own profile or other users' profiles in the same tenant via GET /api/profiles/getCurrentProfile and GET /api/profiles/getOtherProfiles, and fetch the list of conversations associated with their profile via GET /api/conversations/getByCurrentProfile. The implementation includes the necessary API models (ProfileApiModel, UserApiModel, ConversationApiModel), MediatR query/command handlers for data access and caching, and SignalR hubs (ProfileHub, ConversationHub) to support real-time updates.
Features/Conversations, Features/Profiles · high confidence
Introduces core infrastructure for multi-tenancy, caching, and logging
This change establishes the foundational services for the application within the Features/Core module. It introduces a multi-tenancy system via a new OWIN middleware and API base controller that extract tenant identifiers from headers or claims. It also provides a new caching abstraction backed by the .NET MemoryCache, a pluggable logging framework with factory and provider interfaces, and a SignalR hub base class that supports JWT-based authentication. Additionally, it includes utility classes for string manipulation, error handling, and Unity dependency injection integration for Web API filters.
Features/Core · high confidence
Behavioural changes
Introduce soft-delete support and initial data seeding for core entities
The Data layer now supports soft-deletion for core entities (Tenant, Team, User, Channel, Conversation, Message, Profile) via a new \SoftDeleteAttribute\ and an Entity Framework interceptor that automatically filters out deleted records from queries. Additionally, the application now includes database migration configurations that seed a default tenant, team, and system user upon initialization, establishing the foundational data structure for multi-tenant operations.
Data · high confidence
Dependencies
Initial project setup with .NET 4.6.2 and Angular 4.3.0
The project is initialized with a new .NET Framework 4.6.2 backend and an Angular 4.3.0 frontend. The .NET side includes dependencies for Entity Framework 6.1.3, SignalR 2.2.0, Web API 5.2.3, and Unity DI. The frontend side uses Angular 4.3.0 with TypeScript 2.4.0 and Webpack 3.1.0 for building the ClientApp components.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 34 → 31 (-2.9)
- Rubric changed (rubric-2026.08.17 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 73 → 72 (-0.8)
- Architecture 67 → 76 (+9.2)
- Maturity 36 → 38 (+2.1)
- Readiness 13 → 12 (-0.9)
- Security 61 → 48 (-13.6)
Resolved (16)
- As noted, 'Name' in the data model vs 'Firstname'/'Lastname' in the API model is a structural mismatch.
- Build did not complete in the analyzer
- CommentedOutCode (Features/Core/RateLimit.cs)
- High CVE: [GHSA redacted] (packages.config)
- High CVE: [GHSA redacted] (packages.config)
- High CVE: [GHSA redacted] (packages.config)
- Inconsistency in naming the tenant reference: Channel uses 'TenantId' while Message and Conversation use 'Tenant'. This suggests one is a FK and others are navigation properties, but the naming convention is not uniform across entities.
- Medium CVE: [GHSA redacted] (packages.config)
- Medium CVE: [GHSA redacted] (packages.config)
- Medium CVE: [GHSA redacted] (packages.config)
- Medium CVE: [GHSA redacted] (packages.config)
- No exposed public API
- The 'IsDeleted' property is used for soft deletes in Profile, Tenant, and Team. This is consistent. However, the SoftDeleteQueryVisitor and SoftDeleteAttribute suggest a global soft-delete mechanism. The inconsistency is that not all entities (e.g., Message, Conversation) seem to have 'IsDeleted' or the mechanism is applied inconsistently.
- The User model has 'Email', 'Password', 'Id' but lacks a 'Name' or 'Username' property in the data model, whereas the API model has 'Firstname', 'Lastname' and the RegisterCommand has 'Username'. This suggests a gap in the data model or a mismatch in what is persisted vs what is exposed.
- The concept of a user's name is represented by 'Name' in the data model but split into 'Firstname' and 'Lastname' in the API model. This creates a structural inconsistency where one property maps to two, or vice versa.
- single-maintainer — knowledge-concentration (bus factor) risk
New (20)
- Dead code: GetClientIp (Features/Core/RateLimit.cs)
- Documentation: no installation or build instructions (README.md)
- Documentation: no project overview (README.md)
- High CVE: [GHSA redacted] (packages.config)
- High CVE: [GHSA redacted] (packages.config)
- Inconsistent naming for user name components: 'Lastname' and 'Firstname' use the full word 'name', whereas standard API conventions and the rest of the codebase (e.g., 'Username', 'TeamName') often use 'Name' or distinct terms. More critically, 'Lastname' is non-standard compared to 'Surname' or 'LastName' (camelCase), and inconsistent with 'Firstname' which is also non-standard (vs 'FirstName').
- Medium CVE: [GHSA redacted] (packages.config)
- Medium CVE: [GHSA redacted] (packages.config)
- Secret: generic-api-key (Slackish.SelfHost/App.config)
- Secret: generic-api-key (Slackish/App.config)
- The properties Lastname and Firstname in UserApiModel are inconsistent with the standard C# naming convention of LastName and FirstName. While 'Firstname' and 'Lastname' are understandable, they are non-standard compound nouns. In contrast, Username is a single word (or standard compound), and TeamName is a standard compound. The use of 'Firstname' and 'Lastname' stands out as inconsistent with the rest of the codebase's preference for standard PascalCase compounds like TeamName, TenantId, UserId.
- WriteOnlyPrivateField (Features/Core/Logger.cs)
- WriteOnlyPrivateField (Features/Core/RateLimit.cs)
- WriteOnlyPrivateField (Features/Teams/AddOrUpdateTeamCommand.cs)
- WriteOnlyPrivateField (Features/Teams/GetTeamByIdQuery.cs)
- WriteOnlyPrivateField (Features/Teams/GetTeamByNameQuery.cs)
- WriteOnlyPrivateField (Features/Teams/GetTeamsQuery.cs)
- WriteOnlyPrivateField (Features/Teams/RemoveTeamCommand.cs)
- WriteOnlyPrivateField (Security/QueryStringBearerAuthorizeAttribute.cs)
- misleading comment (Features/Core/RateLimit.cs)
API surface
- Unchanged — 4 HTTP endpoints
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
QuinntyneBrown/slackish-v2 was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 05bd973bd60903d3ed4e48d572935950740a1453 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.