APIs Repository - Structure Analysis¶
Project: Psyter REST API Backend
Technology: ASP.NET Web API 2 (.NET Framework 4.7.2)
Audit Date: November 7, 2025
Auditor: AI-Assisted Code Review
Executive Summary¶
The APIs repository contains the core backend REST API for the Psyter mental health telemedicine platform. Built on ASP.NET Web API 2, it serves as the primary data and business logic layer for all client applications (Android, iOS, Web). The architecture follows a traditional three-tier pattern with controllers, repositories, and stored procedures.
Key Findings¶
✅ Strengths:
- Well-organized controller structure with clear separation of concerns
- Consistent use of repository pattern for data access
- Comprehensive API coverage for all business domains
- Strong authentication/authorization framework (OAuth 2.0)
- Extensive integration with third-party services (Firebase, VideoSDK, Payment Gateway)
⚠️ Areas of Concern:
- Using deprecated .NET Framework 4.7.2 (end of support approaching)
- Hardcoded connection strings and secrets in configuration
- Legacy security practices (MD5 hashing found in code)
- No API versioning strategy
- Limited automated testing infrastructure
- Tight coupling to SQL Server stored procedures
Architecture Overview¶
High-Level Architecture¶
┌─────────────────────────────────────────────────────────────┐
│ Client Applications │
│ (Android Client, Android CP, iOS CP, Web Portal) │
└────────────────────┬────────────────────────────────────────┘
│ HTTPS/JSON
▼
┌─────────────────────────────────────────────────────────────┐
│ PsyterAPI (ASP.NET Web API) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Controllers │ │ Providers │ │ Common │ │
│ │ (18 files) │ │ (OAuth 2.0) │ │ (Helpers) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Repositories (Data Access) │ │
│ │ (13 repository classes) │ │
│ └──────────────────────┬──────────────────────────┘ │
└─────────────────────────┼──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SQL Server Databases │
│ ┌────────────────────┐ ┌───────────────────────┐ │
│ │ PsyterDatabase │ │ SchedulingDatabase │ │
│ │ (Main DB) │ │ (Scheduling System) │ │
│ └────────────────────┘ └───────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Architectural Pattern¶
Three-Tier Architecture:
1. Presentation Layer: Controllers expose RESTful endpoints
2. Business Logic Layer: Repositories implement business logic
3. Data Layer: SQL Server with stored procedures
Design Patterns Used:
- ✅ Repository Pattern (data access abstraction)
- ✅ DTO Pattern (Request/Response models)
- ✅ Filter Pattern (authorization, validation, caching)
- ✅ Provider Pattern (OAuth authentication)
- ⚠️ No clear Service Layer (business logic mixed in repositories)
- ⚠️ No Dependency Injection container configured
Project Structure¶
Root Directory Layout¶
APIs/
├── PsyterAPI/ # Main API project
│ ├── App_Start/ # Application startup configuration
│ │ ├── RouteConfig.cs # MVC routing (if used)
│ │ ├── Startup.cs # OWIN OAuth configuration
│ │ └── WebApiConfig.cs # Web API configuration
│ │
│ ├── Common/ # Shared utilities (22 files)
│ │ ├── Security/
│ │ │ ├── SecurityHelper.cs
│ │ │ ├── AuthorizeAttribute.cs
│ │ │ └── AntiXssValidationFilter.cs
│ │ ├── Communication/
│ │ │ ├── EmailManager.cs
│ │ │ ├── SendSMSHelper.cs
│ │ │ └── FCMNotification.cs
│ │ ├── Integration/
│ │ │ ├── VideoSDKHelper.cs
│ │ │ ├── SmartRoutingPaymentInquiryRefund.cs
│ │ │ └── GooglereCaptchaCreateAssessment.cs
│ │ └── Helpers/
│ │ ├── iTextSharpHelper.cs
│ │ ├── GenerateQRCodeHelper.cs
│ │ ├── FTP.cs
│ │ └── XmlHelper.cs
│ │
│ ├── Controllers/ # API endpoint controllers (18 files)
│ │ ├── UserController.cs # Authentication, registration, profile
│ │ ├── ServiceProviderController.cs
│ │ ├── PatientController.cs
│ │ ├── MessagingController.cs
│ │ ├── PaymentController.cs
│ │ ├── NotificationController.cs
│ │ ├── HomeWorkController.cs
│ │ ├── UserPrescriptionController.cs
│ │ ├── AdminController.cs
│ │ ├── CatalogueController.cs
│ │ ├── CommonController.cs
│ │ ├── ContentManagerController.cs
│ │ ├── ClientDiaryController.cs
│ │ ├── ReferralSystemController.cs
│ │ ├── GroupSessionController.cs
│ │ ├── ConferenceEventController.cs
│ │ ├── SEOManagerController.cs
│ │ └── BaseController.cs
│ │
│ ├── Models/ # Data models
│ │ ├── Request/ # Request DTOs
│ │ ├── Response/ # Response DTOs
│ │ └── Entities/ # Domain entities
│ │
│ ├── Providers/ # OAuth providers
│ │ ├── MyAuthorizationServerProvider.cs
│ │ ├── RefreshTokenProvider.cs
│ │ └── OwinExceptionHandlerMiddleware.cs
│ │
│ ├── Repositories/ # Data access layer (23 files)
│ │ ├── BaseRepository.cs # Base repository (empty!)
│ │ ├── DBConstant.cs # Stored procedure names
│ │ ├── UserRepository.cs
│ │ ├── ServiceProviderRepository.cs
│ │ ├── PatientRepository.cs
│ │ ├── BookingPaymentRepository.cs
│ │ ├── SchedulingRepository.cs
│ │ ├── MessagingRepository.cs
│ │ ├── NotificationRepository.cs
│ │ ├── HomeWorkRepository.cs
│ │ ├── UserPrescriptionRepository.cs
│ │ ├── AdminRepository.cs
│ │ ├── ClientDiaryRepository.cs
│ │ ├── CommonRepository.cs
│ │ ├── CatalogueRepository.cs
│ │ ├── ContentManagerRepository.cs
│ │ ├── ReferralRepository.cs
│ │ ├── GroupSessionRepository.cs
│ │ ├── ConferenceEventRepository.cs
│ │ ├── SEOManagerRepository.cs
│ │ ├── ErrorLogRepository.cs
│ │ └── UtilityMethod.cs
│ │
│ ├── Properties/ # Assembly information
│ ├── bin/ # Compiled binaries
│ ├── obj/ # Build objects
│ │
│ ├── firebase-adminsdk.json # 🔐 Firebase credentials (DEV)
│ ├── firebase-adminsdk-live.json # 🔐 Firebase credentials (PROD)
│ ├── MerchantCertificates.p12 # 🔐 Payment gateway certificate
│ ├── Global.asax # Application entry point
│ ├── Global.asax.cs # Application startup logic
│ ├── Web.config # 🔐 Configuration file
│ ├── Web.Debug.config # Debug transformation
│ ├── Web.Release.config # Release transformation
│ ├── log4net.config # Logging configuration
│ ├── packages.config # NuGet packages
│ └── PsyterAPI.csproj # Project file
│
├── packages/ # NuGet packages cache (50+ packages)
├── PsyterAPI.sln # Visual Studio solution
└── azure-pipelines.yml # CI/CD pipeline definition
File Statistics¶
| Component | File Count | Approx Lines |
|---|---|---|
| Controllers | 18 | ~15,000 |
| Repositories | 23 | ~12,000 |
| Common/Helpers | 22 | ~8,000 |
| Models | ~60 | ~6,000 |
| Providers | 3 | ~1,000 |
| Total | ~126 | ~42,000 |
Component Analysis¶
1. Controllers Layer¶
Purpose: Expose RESTful API endpoints for client consumption
Structure:
- All controllers inherit from BaseController (or ApiController)
- Route-based routing with [RoutePrefix] and [Route] attributes
- JSON-only responses (XML formatter removed)
- Authorization via [Common.Authorize] custom attribute
Key Controllers:
UserController.cs (~2,184 LOC)¶
Responsibilities:
- User authentication (username/password, social login)
- User registration and verification
- Profile management (get, update)
- Password management (forgot, reset, change)
- Device registration (FCM tokens)
- User preferences and settings
- Account deletion
Critical Endpoints:
- POST /User/UserLogin - User authentication
- POST /User/RegisterUser - User registration
- GET /User/GetUserProfile/{id} - Get user profile
- PUT /User/UpdateUserProfile - Update profile
- POST /User/ForgotPassword - Password reset
ServiceProviderController.cs (~2,833 LOC)¶
Responsibilities:
- Provider profile management (general access, personal info)
- Professional credentials (work experience, education)
- Documents & certifications (CV, licenses)
- Services offered (pricing, duration)
- Availability & scheduling
- Client management
- Appointments management
- Reviews & ratings
- Revenue & earnings tracking
Critical Endpoints:
- GET /ServiceProvider/GetGeneralAccessDetails/{id}
- PUT /ServiceProvider/UpdatePersonalInfo
- GET /ServiceProvider/GetProviderAvailability/{id}
- POST /ServiceProvider/SetAvailability
- GET /ServiceProvider/SearchProviders
- GET /ServiceProvider/GetProviderRevenue/{id}
PaymentController.cs (~1,959 LOC)¶
Responsibilities:
- Booking order creation
- Payment processing (credit card, wallet)
- Payment gateway integration (SmartRouting)
- Refund processing
- Wallet management
- Promotion codes validation
- Order management
- Provider earnings & payouts
Critical Endpoints:
- POST /BookingPayment/InsertBookingOrder
- POST /BookingPayment/ProcessPayment
- POST /BookingPayment/RequestRefund
- GET /BookingPayment/GetWalletBalance/{id}
- POST /BookingPayment/ValidatePromotionCode
MessagingController.cs (~271 LOC)¶
Responsibilities:
- Send/receive chat messages
- Get conversation lists
- Mark messages as read
- Upload media files
- Block/report users
NotificationController.cs (~1,555 LOC)¶
Responsibilities:
- System notifications (booking, status updates)
- Custom notifications (admin-sent)
- Bulk notifications
- Notification management (read, delete)
- Notification settings
- FCM topic management
Additional Controllers:¶
- PatientController - Screening questionnaires, diary, mood tracking
- HomeWorkController - Homework assignments, submissions, feedback
- UserPrescriptionController - Electronic prescriptions, drug interactions
- AdminController - Provider approval, user management, analytics
- CatalogueController - Master data (countries, specializations)
- CommonController - File uploads, app configuration
- Others - ClientDiary, Referral, GroupSession, ConferenceEvent, ContentManager, SEOManager
Issues Identified:
- ⚠️ Controllers are very large (some >2,000 LOC) - violates Single Responsibility Principle
- ⚠️ Business logic mixed in controllers (should be in service layer)
- ⚠️ No input validation attributes on DTOs (validation done manually)
- ⚠️ Inconsistent error handling across controllers
- ⚠️ No API versioning (e.g., /v1/User/...)
2. Repositories Layer¶
Purpose: Data access abstraction, SQL Server interaction via stored procedures
Issues Found:
BaseRepository.cs - Empty!¶
namespace PsyterAPI.Repositories
{
public class BaseRepository
{
}
}
Problem: Base repository provides no shared functionality. Each repository duplicates:
- Connection string retrieval
- Command timeout configuration
- ADO.NET boilerplate code
- Exception handling
Recommendation: Implement proper base repository with:
protected DataTable ExecuteStoredProcedure(string procName, params SqlParameter[] parameters)
protected T ExecuteScalar<T>(string procName, params SqlParameter[] parameters)
protected int ExecuteNonQuery(string procName, params SqlParameter[] parameters)
Repository Structure¶
- Each repository has methods corresponding to controller actions
- All methods call SQL stored procedures (no inline SQL)
- Uses ADO.NET (no ORM like Entity Framework)
- Manual mapping from DataTable to models
Example Pattern:
public UserLoginResponse AuthenticateUserLogin(UserAuthRequest request)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand("User_Authenticate", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@UserName", request.UserName);
command.Parameters.AddWithValue("@Password", request.Password);
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable dt = new DataTable();
adapter.Fill(dt);
// Manual mapping
return MapToUserLoginResponse(dt);
}
}
Issues:
- ✅ Good: SQL injection protection via stored procedures
- ⚠️ Bad: No connection pooling management (relies on ADO.NET default)
- ⚠️ Bad: Manual DataTable mapping (error-prone, verbose)
- ⚠️ Bad: Duplicate connection handling code across all repositories
- ⚠️ Bad: No transaction management abstraction
- ⚠️ Bad: Tight coupling to SQL Server stored procedures
3. Common/Helpers Layer¶
Purpose: Reusable utility classes for cross-cutting concerns
Security Components:
SecurityHelper.cs (611 LOC)¶
Functions:
- Password hashing (MD5 - DEPRECATED!)
- String encryption/decryption (custom XOR - INSECURE!)
- Token generation
- Connection string encryption/decryption
Critical Issues:
// Line 496 - Hardcoded salt
private static string _salt = "2GlHRj2MxxxC2Dnn"; // Random
// Lines 25-35 - MD5 for password hashing (INSECURE!)
private static string GenerateHash(string pSourceText)
{
UnicodeEncoding Ue = new UnicodeEncoding();
byte[] ByteSourceText = Ue.GetBytes(pSourceText);
MD5CryptoServiceProvider Md5 = new MD5CryptoServiceProvider();
byte[] ByteHash = Md5.ComputeHash(ByteSourceText);
return Convert.ToBase64String(ByteHash);
}
Security Vulnerabilities:
- 🔴 CRITICAL: MD5 hashing for passwords (broken, rainbow table attacks)
- 🔴 CRITICAL: Hardcoded encryption salt
- 🔴 HIGH: Custom XOR encryption (not cryptographically secure)
- 🔴 MEDIUM: No password strength validation
Recommendations:
- Use PBKDF2, bcrypt, or Argon2 for password hashing
- Remove MD5 completely
- Use AES-256-GCM or ChaCha20 for encryption
- Generate cryptographically secure random salts per password
- Implement password strength policies
AntiXssValidationFilter.cs¶
Purpose: Prevent XSS attacks by validating input
Status: ✅ Good implementation (regex-based HTML tag detection)
AuthorizeAttribute.cs¶
Purpose: Custom authorization filter
Status: ✅ Implements bearer token validation
Communication Components:
EmailManager.cs¶
Functions:
- Send emails via SMTP
- Template-based emails
- Verification emails
- Password reset emails
- Booking confirmations
Issues:
- ⚠️ SMTP credentials likely in Web.config (need to verify)
- ⚠️ No rate limiting for email sending
SendSMSHelper.cs¶
Functions:
- Send SMS via gateway
- OTP delivery
- Appointment reminders
FCMNotification.cs¶
Functions:
- Firebase Cloud Messaging integration
- Push notification delivery
- Topic-based notifications
- Multi-device support
Status: ✅ Uses Firebase Admin SDK (good)
Integration Components:
VideoSDKHelper.cs¶
Purpose: VideoSDK API integration for video calls
Functions:
- Create meeting rooms
- Get meeting details
- Manage recordings
SmartRoutingPaymentInquiryRefund.cs¶
Purpose: Payment gateway integration
Functions:
- Process payments
- Handle refunds
- Generate secure hashes
- Certificate-based authentication
Issues:
- ⚠️ Payment certificate (MerchantCertificates.p12) stored in repository
iTextSharpHelper.cs¶
Purpose: PDF generation
Functions:
- Generate prescriptions
- Create invoices
- Generate reports
- HTML to PDF conversion
Status: ✅ Using established library (iTextSharp)
GenerateQRCodeHelper.cs¶
Purpose: QR code generation
Uses: QRCoder library
Status: ✅ Good implementation
4. Models Layer¶
Structure:
- Request Models: DTOs for incoming API requests
- Response Models: DTOs for outgoing API responses
- Entity Models: Domain entities (mapped from database)
Issues:
- ⚠️ No data annotation validation on models
- ⚠️ Models tightly coupled to database structure
- ⚠️ No clear separation between domain models and DTOs
- ⚠️ No model versioning strategy
Example Issues:
// No validation attributes
public class UserRegistrationRequest
{
public string Email { get; set; } // No [EmailAddress] attribute
public string Password { get; set; } // No [Required], [MinLength]
public string PhoneNumber { get; set; } // No [Phone] attribute
}
Should be:
public class UserRegistrationRequest
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(8)]
[RegularExpression(@"^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$")]
public string Password { get; set; }
[Required]
[Phone]
public string PhoneNumber { get; set; }
}
5. Providers Layer¶
Purpose: OAuth 2.0 authentication implementation
MyAuthorizationServerProvider.cs¶
Implements:
- ValidateClientAuthentication - Validate client credentials
- GrantResourceOwnerCredentials - Validate username/password
- TokenEndpoint - Generate access token
- Claims generation (userId, userType, email)
Status: ✅ Follows OAuth 2.0 spec
RefreshTokenProvider.cs¶
Implements:
- Refresh token generation
- Refresh token storage
- Refresh token validation
- Refresh token revocation
Status: ✅ Good implementation
OwinExceptionHandlerMiddleware.cs¶
Purpose: Global exception handler
Status: ✅ Catches unhandled exceptions and logs
Configuration Analysis¶
Web.config¶
Critical Settings:
<!-- Command timeout: 10 minutes (600 seconds) -->
<add key="commandTimeout" value="600"/>
<!-- Max file upload: 100 MB -->
<add key="MaxFileSize" value="104857600"/>
<!-- CORS settings -->
<add key="origins" value="https://dvx.innotech-sa.com,http://localhost:37113"/>
<add key="applyCORS" value="true"/>
<!-- Scheduler API endpoint -->
<add key="SchedulerApiUri" value="https://dvx.innotech-sa.com/Scheduling/SchedulingAPI/authenticate"/>
Security Issues:
🔴 CRITICAL - Custom Errors Disabled:
<customErrors mode="Off"/>
Impact: Detailed error messages exposed to clients (information disclosure)
Fix: Set
mode="On" or mode="RemoteOnly" in production
🔴 CRITICAL - Machine Key Exposed:
<machineKey
decryption="AES"
decryptionKey="CB7B6A9A33A0496D5158CFEB6EB95B0AC538C6BF7F6D8D00851D2A4FB0E24858"
validation="HMACSHA256"
validationKey="C77B221F66E2C665DE95CEFCE724EAF0CEDD5E93D0E95221D64FF3FF7ECA0641FD5491909FB93E10559DA07D317AA91E8B8B7BE2E16F78D0888D48C6D912984B"/>
Impact: Machine keys visible in source code
Fix: Move to Azure Key Vault or encrypted configuration section
🔴 HIGH - Encrypted Connection Strings in Source:
<add name="PsyterDatabase"
connectionString="Data Source=JbvRx05RJB6skIgFYZm1GpKjg2GdF%2FEJEGxZVRWzEfE%3D..." />
Impact: Even encrypted, connection strings shouldn’t be in source control
Fix: Use environment variables or Azure App Configuration
⚠️ MEDIUM - Security Headers Missing:
Missing recommended security headers:
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- Referrer-Policy: no-referrer
- Content-Security-Policy
Current headers:
<customHeaders>
<remove name="X-Powered-By"/>
</customHeaders>
Good: Removes X-Powered-By header ✅
log4net.config¶
Configuration:
- Log file: E:\InnotechProjects\PsyterAPI\PsyterAPI\log4net.config
- Hardcoded path (not portable)
- Size-based rolling (5 MB max)
Issues:
- ⚠️ Hardcoded absolute path in configuration
- ⚠️ No structured logging (JSON format)
- ⚠️ No log aggregation (should use Application Insights, Seq, or ELK)
Database Integration¶
Connection Strings¶
Two databases:
1. PsyterDatabase - Main application database
2. SchedulingDatabase - Scheduling system database
Connection string structure:
- Encrypted using machine key
- Contains: server, database, user, password
Issues:
- ⚠️ Two separate databases create potential consistency issues
- ⚠️ No distributed transaction support mentioned
- ⚠️ No connection pooling configuration visible
Stored Procedure Architecture¶
DBConstant.cs contains 400+ stored procedure name constants.
Benefits:
- ✅ Type-safe procedure names
- ✅ Centralized maintenance
- ✅ SQL injection prevention
- ✅ Compile-time checking
Drawbacks:
- ⚠️ Tight coupling to database schema
- ⚠️ Difficult to version API without DB changes
- ⚠️ No ORM benefits (change tracking, lazy loading)
- ⚠️ Stored procedure logic not in source control (separate DB scripts needed)
Recommendation: Consider hybrid approach:
- Complex reports: stored procedures
- CRUD operations: Entity Framework Core
- Migrations: Entity Framework migrations for versioning
Third-Party Dependencies¶
Package Analysis¶
Core Framework:
- ASP.NET Web API 5.2.7 ✅ (stable)
- ASP.NET MVC 5.2.3 ✅ (for any views/documentation)
- .NET Framework 4.7.2 ⚠️ (end of support: 2027-01-12)
Authentication:
- Microsoft.Owin 3.1.0 ✅
- Microsoft.Owin.Security.OAuth 3.1.0 ✅
- JWT 10.1.1 ⚠️ (old version, consider System.IdentityModel.Tokens.Jwt)
Firebase:
- FirebaseAdmin 3.0.0 🔴 OUTDATED (current: 3.0.1+)
- Google.Apis.FirebaseCloudMessaging.v1 1.68.0.3431 ✅
PDF Generation:
- iTextSharp 5.5.13.3 ⚠️ (old, commercial license required for newer versions)
- itextsharp.xmlworker 5.5.13.3 ⚠️
Serialization:
- Newtonsoft.Json 13.0.3 ✅ (latest stable)
Logging:
- log4net 2.0.8 ✅
Security:
- BouncyCastle 1.8.9 ⚠️ (outdated, current: 2.x)
Other:
- AutoMapper 7.0.1 🔴 VERY OUTDATED (current: 13.x)
- QRCoder 1.4.3 ⚠️ (current: 1.6.x)
Dependency Security Scan Needed¶
Recommendations:
1. Run dotnet list package --vulnerable to check for known vulnerabilities
2. Update AutoMapper to latest version
3. Update Firebase SDK
4. Update BouncyCastle
5. Consider migrating to .NET 8 (long-term support)
Authentication & Authorization¶
OAuth 2.0 Implementation¶
Flow: Resource Owner Password Credentials Grant (ROPC)
Token Endpoint: /token
Request:
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=user@example.com&password=secret123
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "..."
}
Token Lifetime: 30 days (configurable in Startup.cs)
Claims Structure:
- sub - User ID
- userLoginInfoId - User login info ID
- userType - User type (1=Client, 2=Provider, 3=Admin)
- email - User email
Authorization Levels:
1. Public - No authorization required (login, register)
2. Authenticated - [Common.Authorize] - Any logged-in user
3. Role-Based - [ValidateCareProviderOrClientClaim] - Specific user type
4. Resource-Based - Token userLoginInfoId must match resource owner
Issues:
- ⚠️ ROPC grant type is not recommended (user credentials exposed to client)
- ⚠️ Should use Authorization Code Flow with PKCE for mobile apps
- ⚠️ No token revocation endpoint
- ⚠️ Refresh tokens stored in database (no cleanup of expired tokens)
- ✅ Good: Token expiration enforced
- ✅ Good: Claims-based authorization
Error Handling & Logging¶
Global Exception Handler¶
Implementation: GlobalExceptionHandler.cs (action filter)
Catches:
- Unhandled exceptions in controllers
- Model validation failures
- Authorization failures
Logs:
- Exception message and stack trace
- User ID (if authenticated)
- Controller and action name
- Request parameters
- Timestamp
Response Format:
{
"Status": 0,
"Message": "An error occurred",
"Reason": "Error",
"ErrorId": "ERR-12345"
}
Issues:
- ⚠️ Error messages may leak sensitive information
- ⚠️ No error code categorization (all errors = “Error”)
- ⚠️ No correlation IDs for distributed tracing
- ⚠️ Stack traces visible to clients (in dev mode)
Logging¶
Framework: log4net
Log Levels: ALL (configurable)
What’s Logged:
- All exceptions
- Authentication attempts (likely)
- Payment transactions (likely)
- Admin actions (likely)
Issues:
- ⚠️ No structured logging (plain text, hard to query)
- ⚠️ No centralized log aggregation
- ⚠️ Hardcoded log file path
- ⚠️ No performance logging (request duration, slow queries)
Recommendations:
- Switch to Serilog or NLog with structured logging
- Integrate with Application Insights or Seq
- Add correlation IDs for request tracing
- Implement request/response logging middleware
API Design & Conventions¶
Routing¶
Strategy: Attribute-based routing
Pattern:
[RoutePrefix("User")]
public class UserController : BaseController
{
[Route("UserLogin")]
[HttpPost]
public IHttpActionResult UserLogin(UserAuthRequest request)
{
// ...
}
}
Result: /User/UserLogin endpoint
Issues:
- ⚠️ Inconsistent naming (some use verbs: UserLogin, others use nouns)
- ⚠️ No API versioning (e.g., /v1/User/Login)
- ⚠️ No hypermedia/HATEOAS links in responses
- ⚠️ Mixing RPC-style (UserLogin) with REST-style (/users/:id)
Better REST Conventions:
- POST /api/v1/auth/login (not /User/UserLogin)
- GET /api/v1/users/{id} (not /User/GetUserProfile/{id})
- PUT /api/v1/users/{id} (not /User/UpdateUserProfile)
- POST /api/v1/appointments (not /BookingPayment/InsertBookingOrder)
Request/Response Format¶
Content-Type: application/json (only)
Response Wrapper:
{
"Status": 1,
"Message": "Success",
"Reason": "Success",
"Data": { ... }
}
Issues:
- ⚠️ Wrapper adds unnecessary nesting (non-standard)
- ⚠️ Status code in body duplicates HTTP status code
- ✅ Good: Consistent structure across all endpoints
Standard REST Response (Preferred):
HTTP/1.1 200 OK
Content-Type: application/json
{
"userId": 123,
"email": "user@example.com",
...
}
With errors:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://api.psyter.com/errors/validation",
"title": "Validation Failed",
"status": 400,
"errors": {
"email": ["Email is required"]
}
}
Pagination¶
Current Implementation: Page number + page size
Example:
{
"PageNumber": 1,
"PageSize": 20
}
Issues:
- ⚠️ No total count in response
- ⚠️ No next/previous links
- ⚠️ Offset-based pagination (performance issues for large datasets)
Better Approach:
{
"data": [...],
"pagination": {
"total": 1000,
"page": 1,
"pageSize": 20,
"totalPages": 50,
"hasNext": true,
"hasPrevious": false,
"nextPage": "/api/v1/users?page=2&pageSize=20"
}
}
Or use cursor-based pagination for better performance.
Security Assessment¶
Security Strengths ✅¶
- OAuth 2.0 Authentication - Industry standard
- Bearer Token Authorization - Stateless authentication
- Anti-XSS Validation - Input sanitization
- Stored Procedures - SQL injection prevention
- HTTPS Enforcement - TLS 1.2+ required
- CORS Configuration - Restricted origins
- Firebase Admin SDK - Secure push notifications
Security Vulnerabilities 🔴¶
CRITICAL¶
-
MD5 Password Hashing
- Location:SecurityHelper.cs:25-35
- Impact: Passwords easily cracked via rainbow tables
- Fix: Migrate to PBKDF2, bcrypt, or Argon2
- Effort: HIGH (requires password reset for all users) -
Hardcoded Encryption Keys
- Location:Web.config:36(machineKey),SecurityHelper.cs:496(salt)
- Impact: If keys leaked, all encrypted data compromised
- Fix: Use Azure Key Vault or environment variables
- Effort: MEDIUM -
Custom Errors Disabled
- Location:Web.config:33
- Impact: Stack traces and sensitive info exposed to attackers
- Fix:<customErrors mode="On" />
- Effort: LOW -
Connection Strings in Source Control
- Location:Web.config:51-57
- Impact: Database credentials exposed if repo compromised
- Fix: Use Azure App Configuration or Key Vault
- Effort: MEDIUM -
Firebase Credentials in Repository
- Location:firebase-adminsdk.json,firebase-adminsdk-live.json
- Impact: Unauthorized access to Firebase services
- Fix: Use environment variables or secure file storage
- Effort: LOW -
Payment Certificate in Repository
- Location:MerchantCertificates.p12
- Impact: Unauthorized payment processing
- Fix: Move to Azure Key Vault
- Effort: MEDIUM
HIGH¶
-
No Rate Limiting
- Impact: API abuse, DDoS, brute force attacks
- Fix: Implement rate limiting middleware (AspNetCoreRateLimit)
- Effort: MEDIUM -
No Request Validation (CSRF for state-changing operations)
- Impact: Cross-site request forgery attacks
- Fix: Implement anti-forgery tokens or SameSite cookies
- Effort: MEDIUM -
Weak Session/Token Management
- Impact: Token theft, session hijacking
- Fix: Implement token rotation, blacklisting
- Effort: MEDIUM
MEDIUM¶
-
Missing Security Headers
-X-Frame-Options,X-Content-Type-Options,CSP,Referrer-Policy
- Fix: Add to Web.config
- Effort: LOW -
No Input Validation Attributes
- Impact: Malformed data reaching business logic
- Fix: Add data annotations to models
- Effort: MEDIUM -
Verbose Error Messages
- Impact: Information disclosure
- Fix: Implement user-friendly error messages
- Effort: MEDIUM
Performance Considerations¶
Potential Bottlenecks¶
-
Database Queries
- Command timeout: 10 minutes (very high!)
- No query optimization visible
- Potential N+1 query problems
- No caching layer -
Large File Uploads
- Max size: 100 MB
- No chunking/streaming mentioned
- All uploaded to memory first (likely) -
Synchronous I/O
- Most controller methods appear synchronous
- No async/await pattern visible in samples
- Blocks threads during I/O operations -
No Response Caching
- Master data (countries, specializations) requested repeatedly
- No ETags or cache headers -
PDF Generation
- Synchronous operation (blocks request)
- Should be background job
Recommendations¶
-
Implement Caching
- UseMemoryCacheor Redis for frequently accessed data
- Add cache headers for static resources
- Implement ETags for conditional requests -
Use Async/Await
- Convert all I/O operations to async
- Useasync Task<IHttpActionResult>for controller actions
- Useasync/awaitin repositories -
Add Response Compression
- Enable gzip compression in IIS
- Reduce payload sizes by 70-90% -
Optimize Database Access
- Review stored procedures for optimization
- Add database indexes
- Implement connection pooling settings
- Use compiled queries where appropriate -
Implement Background Jobs
- Use Hangfire or Azure Functions for:- PDF generation
- Email sending
- Notification delivery
- Payment reconciliation
Testing & Quality Assurance¶
Current State¶
Observations:
- ❌ No test projects found in solution
- ❌ No unit tests
- ❌ No integration tests
- ❌ No API tests (Postman collections)
- ❌ No code coverage reports
- ❌ No static code analysis
Impact:
- High risk of regressions
- No confidence in refactoring
- Unknown code coverage
- Manual testing required for every change
Recommendations¶
-
Unit Testing
- Use xUnit or NUnit
- Mock repositories with Moq
- Test business logic in isolation
- Target: 70%+ code coverage -
Integration Testing
- Test API endpoints end-to-end
- Use test database (separate from dev)
- Test authentication/authorization flows -
API Testing
- Create Postman collections
- Export as Newman tests for CI/CD
- Test all happy paths and error cases -
Static Code Analysis
- Enable Roslyn analyzers
- Use SonarQube or SonarCloud
- Set quality gates in CI/CD -
Load Testing
- Use JMeter or k6
- Test concurrent user scenarios
- Identify performance bottlenecks
CI/CD Pipeline¶
Azure DevOps Pipeline¶
File: azure-pipelines.yml
Trigger: Push to master branch
Agent Pool: DevWebServerAgentPool (self-hosted)
Build Steps:
1. NuGet restore
2. MSBuild (Release configuration)
3. Package Web Deploy
4. Publish artifacts
5. Deploy to D:\ROOT\Development\Psyter\Master\APIs
Issues:
- ⚠️ No automated tests in pipeline
- ⚠️ No code quality checks
- ⚠️ No security scanning
- ⚠️ Deploys directly to dev server (no staging/approval)
- ⚠️ Uses self-hosted agent (single point of failure)
Recommendations:
1. Add test stage before deployment
2. Add code quality gate (SonarQube)
3. Add security scanning (OWASP Dependency Check)
4. Implement blue-green or canary deployments
5. Add manual approval for production
6. Use Microsoft-hosted agents for build (use self-hosted only for deploy)
Deployment Architecture¶
Current Deployment¶
Environment: Development
Server: dev2.innotech-sa.com
Path: D:\ROOT\Development\Psyter\Master\APIs
Web Server: IIS (inferred)
Framework: .NET Framework 4.7.2
Issues:
- ⚠️ Hardcoded paths in configuration
- ⚠️ No environment-specific configurations (except Web.Debug/Release)
- ⚠️ Manual database migration process (assumed)
Recommended Architecture¶
Environments:
1. Development - Dev server, auto-deploy from dev branch
2. Staging - Pre-production, manual deploy, approval required
3. Production - Live, manual deploy, approval required
Infrastructure:
- Hosting: Azure App Service or Azure Container Apps
- Database: Azure SQL Database with geo-replication
- Configuration: Azure App Configuration
- Secrets: Azure Key Vault
- Monitoring: Application Insights
- CDN: Azure CDN for static assets
- Load Balancer: Azure Front Door
Scalability:
- Horizontal scaling via App Service Plan
- Connection pooling optimization
- Implement caching (Redis)
- Use CDN for static content
Documentation Status¶
Current Documentation¶
✅ Available:
- Detailed structure documentation (DETAILED_STRUCTURE_APIS_PART1.md, PART2.md)
- Azure pipeline configuration
❌ Missing:
- API documentation (Swagger/OpenAPI spec)
- Setup/installation guide
- Database schema documentation
- Stored procedure documentation
- Deployment guide
- Troubleshooting guide
- Architecture decision records (ADRs)
Recommendations¶
-
Generate OpenAPI Specification
- Install Swashbuckle.AspNet
- Add Swagger UI endpoint
- Document all endpoints with XML comments -
Create README.md
- Prerequisites
- Local setup instructions
- Configuration guide
- Running the application -
Document Database Schema
- ER diagrams
- Table descriptions
- Stored procedure catalog -
Create Deployment Runbook
- Step-by-step deployment process
- Rollback procedures
- Health check verification
Modernization Roadmap¶
Phase 1: Immediate (0-3 months)¶
Security Fixes:
- ✅ Migrate MD5 to PBKDF2/bcrypt
- ✅ Move secrets to Azure Key Vault
- ✅ Enable custom errors in production
- ✅ Add security headers
- ✅ Implement rate limiting
Documentation:
- ✅ Add Swagger/OpenAPI
- ✅ Create README and setup guide
- ✅ Document API endpoints
Testing:
- ✅ Add unit test project
- ✅ Write tests for critical paths
- ✅ Add tests to CI/CD pipeline
Phase 2: Short-term (3-6 months)¶
Code Quality:
- ✅ Implement proper base repository
- ✅ Add input validation attributes
- ✅ Refactor large controllers (SRP)
- ✅ Add service layer
- ✅ Implement async/await
Performance:
- ✅ Add response caching
- ✅ Optimize database queries
- ✅ Implement background jobs
- ✅ Add compression
Infrastructure:
- ✅ Migrate to Azure App Service
- ✅ Setup staging environment
- ✅ Implement blue-green deployment
Phase 3: Medium-term (6-12 months)¶
Framework Upgrade:
- ✅ Migrate to .NET 8 (ASP.NET Core Web API)
- ✅ Replace ADO.NET with Entity Framework Core
- ✅ Implement dependency injection
- ✅ Add API versioning
Architecture:
- ✅ Introduce service layer
- ✅ Implement CQRS pattern (for complex domains)
- ✅ Add message queue (Azure Service Bus)
- ✅ Implement event-driven architecture
Phase 4: Long-term (12+ months)¶
Microservices:
- ✅ Split into domain-based services:
- User Service
- Booking Service
- Payment Service
- Notification Service
- Messaging Service
- ✅ Implement API Gateway (Azure API Management)
- ✅ Setup service mesh
Scalability:
- ✅ Container orchestration (Kubernetes/AKS)
- ✅ Auto-scaling policies
- ✅ Multi-region deployment
- ✅ CDN for global reach
Summary & Recommendations¶
Overall Assessment¶
Grade: C+ (Functional but needs significant improvements)
Strengths:
- ✅ Comprehensive API coverage
- ✅ OAuth 2.0 authentication
- ✅ Stored procedures prevent SQL injection
- ✅ Well-organized controller structure
- ✅ Good third-party integrations (Firebase, VideoSDK, Payment Gateway)
Critical Weaknesses:
- 🔴 MD5 password hashing (security risk)
- 🔴 Secrets in source control (security risk)
- 🔴 No automated testing (quality risk)
- 🔴 Deprecated .NET Framework (maintenance risk)
- 🔴 No API documentation (usability risk)
Priority Actions¶
Do Now (Next 2 Weeks)¶
-
Security:
- Enable custom errors:<customErrors mode="On" />
- Remove Firebase credentials from repo
- Remove payment certificate from repo
- Add security headers to Web.config -
Documentation:
- Install Swashbuckle and add Swagger UI
- Create basic README with setup instructions
Do Next (Next 1-2 Months)¶
-
Security:
- Migrate password hashing from MD5 to PBKDF2
- Move all secrets to Azure Key Vault
- Implement rate limiting
- Add input validation attributes -
Testing:
- Create unit test project
- Write tests for critical business logic
- Add tests to CI/CD pipeline -
Code Quality:
- Implement proper BaseRepository
- Refactor controllers >1000 LOC
- Add service layer
Plan (Next 3-6 Months)¶
-
Framework Upgrade:
- Plan migration to .NET 8
- Setup proof-of-concept for one controller
- Create migration strategy -
Infrastructure:
- Setup staging environment
- Migrate to Azure App Service
- Implement Application Insights -
Performance:
- Add response caching
- Optimize slow queries
- Implement background jobs (Hangfire)
Conclusion¶
The Psyter APIs repository provides a comprehensive backend for the mental health telemedicine platform. While functionally complete, it requires significant modernization efforts, particularly in security, testing, and framework upgrades. The transition from .NET Framework 4.7.2 to .NET 8 should be a top priority, along with addressing critical security vulnerabilities.
The current architecture is serviceable for the immediate term but will struggle to scale. A phased approach to modernization, starting with security fixes and adding automated testing, will provide a solid foundation for future growth.
Next Steps:
- Review and prioritize recommendations
- Create detailed implementation plans for each phase
- Assign ownership for critical security fixes
- Schedule .NET 8 migration planning session
End of Structure Analysis Document