Web Repository - Structure Analysis

Executive Summary

The Psyter Web Application is a comprehensive ASP.NET MVC 5 application serving as the primary web portal for the telemedicine platform. It implements a traditional three-tier architecture with MVC pattern, supports bilingual content (English/Arabic with RTL), and provides extensive functionality for multiple user roles.

Architecture Pattern: Model-View-Controller (MVC)
Framework: ASP.NET MVC 5.2.3 on .NET Framework 4.7.2
Lines of Code: ~60,000+ (estimated)
Primary Language: C# with Razor views, JavaScript

Architecture Overview

High-Level Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Client Browser                            │
│  (HTML/CSS/JavaScript - Bilingual EN/AR with RTL)           │
└────────────┬────────────────────────────────────────────────┘
             │ HTTPS
             │
┌────────────▼────────────────────────────────────────────────┐
│                  ASP.NET MVC Application                     │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              Presentation Layer                       │  │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────┐     │  │
│  │  │Controllers │  │   Views    │  │   Filters  │     │  │
│  │  │  (Action   │  │  (Razor)   │  │ (Auth/Role)│     │  │
│  │  │  Methods)  │  │            │  │            │     │  │
│  │  └────────────┘  └────────────┘  └────────────┘     │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              Business Logic Layer                     │  │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────┐     │  │
│  │  │  Common    │  │   Models   │  │ Validators │     │  │
│  │  │  Utilities │  │  (DTOs)    │  │            │     │  │
│  │  └────────────┘  └────────────┘  └────────────┘     │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              Data Access Layer                        │  │
│  │  ┌────────────┐  ┌────────────┐                      │  │
│  │  │  API       │  │  DAL       │                      │  │
│  │  │  DataAccess│  │  Manager   │                      │  │
│  │  └────────────┘  └────────────┘                      │  │
│  └──────────────────────────────────────────────────────┘  │
└────────────┬────────────────────────────────────────────────┘
             │ HTTP/HTTPS API Calls
             │
┌────────────▼────────────────────────────────────────────────┐
│                    Backend APIs                              │
│  ├─ PsyterAPI (Main Backend)                                │
│  ├─ Media Upload API                                        │
│  ├─ Scheduling API                                          │
│  └─ Google Analytics API                                    │
└─────────────────────────────────────────────────────────────┘

Application Layers

1. Presentation Layer

Controllers (/Controllers)
- Organization: Role-based and feature-based grouping
- Key Controllers:
- WebController - Public pages, home, about, FAQ
- UserManagerController - User authentication, registration
- ClientController - Patient-specific features
- ServiceProviderController - Care provider features
- Admin/CatalogueController - Admin catalog management
- AccountantController - Financial features
- CollaborationController - Collaboration features
- CommonController - Shared endpoints

Views (/Views)
- Organization: By role and language
- Structure:

Views/
├── Web/
│   ├── English/
│   └── Arabic/
├── Patient/
├── Physician/
├── Admin/
├── Shared/
│   ├── _Layout.cshtml
│   ├── _Layout_AR.cshtml
│   └── Partials/

Filters (/Filters)
- AuthenticateUser - Session-based authentication
- IsAdmin, IsClient, IsServiceProvider - Role-based authorization
- IsAccountant, IsMarkeetingManager, IsSeoManager, IsContentManager - Specialized roles
- exceptionFilter - Global exception handling
- CustomRouting - Custom route handling

2. Business Logic Layer

Common Utilities (/Common)

AppConstants.cs               // Application-wide constants
APIAuthenticationToken.cs     // API token management
Common.cs                      // Helper methods, SEO data, utilities

Models (/Models)
- Domain Models:
- UserProfile, PersonalInformation, ContactInformation
- Availability, Booking, Appointment
- Prescription, Scrc (clinical records)
- WorkExperience, EducationHistory, CvDetails
- GroupSessionViewModel, RefundPayment

  • Request DTOs (/Models/Request):
  • UserRegistrationRequest, UserAuthRequest
  • AvailabilityBookingRequest
  • CatalogueRequest, FilterCriteria
  • GoogleAnalyticsReportRequest

  • Response DTOs (/Models/Response):

  • UserAuthResponse, UserRegistrationResponse
  • ServiceProviderResponse, AvailabilityResponse
  • CatalogueResponse, CommonResponse
  • APIAuthTokensResponse

  • Catalog Models:

  • CatSpeciality, CatEducationType, CatPhysicianRole
  • CatSalutation, CatUserPreference, CatScreeningQuestion

  • Enums (/Models/Enums):

  • Enumeration.cs, Enum.cs - Application enumerations

Session Management (/Models)
- SessionVariables.cs - Session key constants
- UserLoginInfo.cs - User session data
- APIAuthToken.cs - API authentication tokens

3. Data Access Layer

API Communication (/DataAccess)

ApiDataAccess.cs
├── Constructor: Initializes HttpClient with base URL
├── Authentication Methods
   ├── GetUserDetails(username, password)
   └── Token management
├── User Management
   ├── RegisterUser(UserRegistrationRequest)
   ├── VerifyUser(verificationCode)
   └── User CRUD operations
├── Catalog Methods
   ├── GetPhysicianRoles()
   ├── GetSpecialities()
   ├── GetCountries()
   └── Other catalog data
└── Generic Methods
    ├── GET requests
    ├── POST requests
    └── File uploads

DALManager.cs
├── API type enumeration (Psyter, Scheduling, etc.)
├── Constructor: API-specific initialization
├── Generic Data Methods
   ├── GetData(endpoint, method, token)
   ├── PostData(data, endpoint, method, token)
   ├── PutData(data, endpoint, method, token)
   └── DeleteData(endpoint, method, token)
└── Error handling and logging

Component Breakdown

Controllers Structure

Controllers/
├── Admin/
│   └── Catalogue/
│       ├── CatalogueController.cs         (1,200+ lines)
│       ├── ManagePromotionController.cs   (350+ lines)
│       ├── PaymentController.cs           (1,800+ lines)
│       ├── PhysicianListController.cs     (600+ lines)
│       └── UserPreferenceController.cs    (450+ lines)
├── Accountant/
│   └── AccountantController.cs            (500+ lines)
├── Patient/
│   ├── ClientController.cs                (2,500+ lines)
│   └── ScreeningController.cs             (400+ lines)
├── Physician/
│   ├── ServiceProviderController.cs       (3,700+ lines) ⚠️ Very large
│   ├── PhysicianAvailabilityController.cs (1,100+ lines)
│   └── PrescriptionController.cs          (300+ lines)
├── CollaborationController.cs             (250+ lines)
├── CommonController.cs                    (1,500+ lines)
├── ContentManagerController.cs            (200+ lines)
├── ErrorController.cs                     (100+ lines)
├── EventController.cs                     (800+ lines)
├── MarkeetingController.cs                (500+ lines)
├── OrganizationController.cs              (400+ lines)
├── SEOManagerController.cs                (300+ lines)
├── UserManagerController.cs               (2,800+ lines)
├── UserPreferenceDataController.cs        (200+ lines)
└── WebController.cs                       (900+ lines)

Views Organization

Public Views (/Views/Web)
- Home, About, FAQ, Contact
- Privacy Policy, Terms & Conditions
- Care Provider Listings
- Blog/Content pages
- Psychological Tests/Screening

Patient Views (/Views/Patient)
- Dashboard
- Profile management
- Appointment booking
- Session history
- Messaging
- Diary/Journal
- Homework

Care Provider Views (/Views/Physician)
- Dashboard
- Profile/CV management
- Schedule/Availability
- Patient management
- Appointment list
- Prescription creation
- Group session management
- Payslip/Financial reports

Admin Views (/Views/Admin)
- User management
- Catalog management
- Promotion management
- Reports
- Configuration

Shared Components (/Views/Shared)
- _Layout.cshtml - English layout
- _Layout_AR.cshtml - Arabic layout (RTL)
- Partial views for reusable components
- Error pages

Static Assets Organization

Stylesheets (/Content)

Content/
├── css/
│   ├── Arabic/                    # RTL-specific styles
│   │   ├── bootstrap.min.css
│   │   ├── style-*.css
│   │   └── ui-date-picker-ar.css
│   ├── style-*.css                # Feature-specific styles
│   ├── bootstrap.min.css
│   └── font-awesome.min.css
├── stylesheets/
│   ├── pages-stylesheets/         # Page-specific styles
│   │   ├── style-home-page.css
│   │   ├── style-appointment-page.css
│   │   └── ...
│   └── bootstrap*.css
├── fonts/                         # Custom fonts
│   ├── Alexandria/                # Arabic font
│   ├── Lato/                      # English font
│   └── webfonts/                  # Font Awesome
├── images/                        # Application images
│   ├── img/                       # Organized images
│   ├── meeting/                   # Video meeting icons
│   └── mobileappimages/           # Mobile app download
└── svgs/                          # SVG icons

JavaScript (/Scripts)

Scripts/
├── JS/                            # Custom JavaScript
│   ├── AdminManageOrganizations.js
│   ├── BookGroupSession.js
│   ├── ClientPackages.js
│   ├── join-meeting-conference.js
│   ├── join-meeting-guest.js
│   ├── ManageGroupSession.js
│   ├── OrganizationDashboard.js
│   ├── PayForReservedSlots.js
│   └── QuestionnaireHistory.js
├── sweat-alert/                   # Alert library
├── jquery-*.js                    # jQuery library
└── Third-party libraries

Key Design Patterns

1. MVC Pattern

  • Model: DTOs for API communication, view models
  • View: Razor templates with bilingual support
  • Controller: Orchestrates business logic, API calls

2. Repository Pattern (Implicit)

  • ApiDataAccess acts as repository for API operations
  • DALManager provides abstraction over different API types

3. Filter Pattern

  • Custom action filters for authentication/authorization
  • Exception handling filter
  • Route handling filter

4. Session State Pattern

  • User authentication via session
  • API tokens cached in session
  • User preferences in session

5. DTO Pattern

  • Separate request/response models
  • Clean API contract boundaries
  • Type-safe data transfer

Data Flow

Typical Request Flow

1. Browser Request
   ├─> IIS/IIS Express
   │
2. ASP.NET Pipeline
   ├─> Authentication Filter (Session validation)
   ├─> Authorization Filter (Role check)
   ├─> Controller Action
   │   ├─> Session data retrieval
   │   ├─> Build API request (DTO)
   │   ├─> Call DALManager/ApiDataAccess
   │   │   ├─> HTTP request to backend API
   │   │   ├─> Deserialize JSON response
   │   │   └─> Return response DTO
   │   ├─> Process response data
   │   ├─> Prepare View Model
   │   └─> Return View Result
   │
3. View Rendering
   ├─> Select language-specific view
   ├─> Render Razor template
   ├─> Apply layout (_Layout or _Layout_AR)
   ├─> Include CSS/JS bundles
   └─> Generate HTML
   │
4. Response to Browser
   └─> HTML/JSON with security headers

API Communication Pattern

// Example: Getting user profile
public async Task<ActionResult> GetProfile()
{
    // 1. Get session data
    var userInfo = (UserLoginInfo)Session[SessionVariables.UserLoginInfo];
    var apiTokens = (APIAuthTokensResponse)Session[SessionVariables.APIAuthTokenList];

    // 2. Prepare API request
    var dalManager = new DALManager(ApiType.psyter);

    // 3. Call API
    JObject response = await dalManager.GetData(
        userInfo.UserID.ToString(),
        PsyterApiMethodNames.UserProfile,
        apiTokens.APIAuthToken.access_token
    );

    // 4. Deserialize response
    var profileResponse = response.ToObject<UserProfileResponse>();

    // 5. Return view with data
    return View(profileResponse);
}

Configuration Management

Application Settings (Web.config)

<appSettings>
  <!-- API Endpoints -->
  <add key="PsyterApiBasePath" value="https://..." />

  <!-- Application Token -->
  <add key="PsyterApplicationToken" value="..." />

  <!-- Session Configuration -->
  <add key="SessionTimeoutCountDown" value="180" />

  <!-- JSON Serialization -->
  <add key="aspnet:MaxJsonDeserializerMembers" value="10000000"/>
</appSettings>

Security Configuration

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="X-Frame-Options" value="SAMEORIGIN" />
      <add name="X-Xss-Protection" value="1; mode=block" />
      <add name="X-Content-Type-Options" value="nosniff" />
      <add name="Referrer-Policy" value="same-origin" />
      <add name="Strict-Transport-Security" value="max-age=31536000" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Bilingual Support Architecture

Language Management

Session[SessionVariables.CurrentLanguage]
├─> "en" (English) or "ar" (Arabic)
│
View Selection
├─> ~/Views/[Area]/English/[View].cshtml
└─> ~/Views/[Area]/Arabic/[View].cshtml

CSS Selection
├─> /Content/css/style-*.css (LTR)
└─> /Content/css/Arabic/style-*-ar.css (RTL)

Layout Selection
├─> ~/Views/Shared/_Layout.cshtml (LTR)
└─> ~/Views/Shared/_Layout_AR.cshtml (RTL)

Implementation Example

public async Task<ActionResult> Home()
{
    string viewPath = "";
    if (Session[SessionVariables.CurrentLanguage].ToString() == AppConstants.Languages.English)
    {
        viewPath = "~/Views/Web/English/Home.cshtml";
    }
    else
    {
        viewPath = "~/Views/Web/Arabic/Home.cshtml";
    }
    return View(viewPath);
}

Authentication & Authorization Flow

User Request
│
▼
[AuthenticateUser Filter]
├─> Check Session[UserLoginInfo]
├─> If null → Redirect to Login
└─> If valid → Continue
    │
    ▼
    [Role-Based Filter] (IsClient, IsAdmin, etc.)
    ├─> Check Session[UserLoginInfo].RoleID
    ├─> If unauthorized → Redirect to Access Denied
    └─> If authorized → Execute Action
        │
        ▼
        Controller Action
        └─> Business Logic

Filter Implementation

public class IsClient : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var userInfo = (UserLoginInfo)HttpContext.Current.Session[SessionVariables.UserLoginInfo];

        if (userInfo == null || userInfo.RoleID != (int)UserRoles.Client)
        {
            filterContext.Result = new RedirectResult("~/Error/AccessDenied");
        }
    }
}

Session Management

Session Variables (SessionVariables.cs)

- CurrentLanguage           // "en" or "ar"
- UserLoginInfo            // User authentication data
- APIAuthTokenList         // API access tokens
- UserProfileInfo          // Cached user profile
- SelectedCareProvider     // Currently viewing provider
- BookingInfo              // Appointment booking data
- PaymentInfo              // Payment transaction data

Session Lifecycle
1. Session_Start - Initialize common data, get API tokens
2. During Request - Read/write session data
3. Session Timeout - Redirect to login (configured: 180 seconds)

Error Handling

Global Exception Filter

public class exceptionFilter : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        // Log exception
        // Set error view
        // Clear response
        filterContext.ExceptionHandled = true;
    }
}

Error Controller

ErrorController
├─> NotFound() - 404 errors
├─> AccessDenied() - 403 errors
└─> ServerError() - 500 errors

Performance Considerations

Bundling & Minification (BundleConfig.cs)

bundles.Add(new ScriptBundle("~/bundles/jquery")
    .Include("~/Scripts/jquery-{version}.js"));

bundles.Add(new StyleBundle("~/Content/css")
    .Include("~/Content/bootstrap.css", "~/Content/site.css"));

Caching Strategy
- Static content caching (CSS, JS, images)
- API token caching in session
- Application Insights for monitoring

External Integrations

  1. Google Analytics
    - Google.Analytics.Data.V1Beta package
    - Analytics reporting features
    - Custom event tracking

  2. Application Insights
    - Microsoft.ApplicationInsights packages
    - Performance monitoring
    - Exception tracking
    - Dependency tracking

  3. Payment Gateway
    - Payment processing in PaymentController
    - Merchant certificates (MerchantCertificates.p12)

  4. Video Conferencing
    - Video session UI in /Content/images/meeting/
    - WebRTC implementation (likely in JavaScript)

Technical Debt & Concerns

Code Organization Issues

  1. Oversized Controllers ⚠️ Critical
    - ServiceProviderController.cs - 3,700+ lines
    - ClientController.cs - 2,500+ lines
    - UserManagerController.cs - 2,800+ lines
    - Should be split into smaller, focused controllers

  2. Mixed Responsibilities
    - Controllers handling both UI and API logic
    - Business logic in controllers instead of services
    - Direct API calls from controllers

  3. Code Duplication
    - Similar view selection logic across controllers
    - Repeated session management code
    - Duplicate API call patterns

Architectural Issues

  1. No Service Layer
    - Business logic directly in controllers
    - API calls from controllers
    - Difficult to test and maintain

  2. Tight Coupling
    - Controllers tightly coupled to API structure
    - Session dependency throughout application
    - Hard-coded view paths

  3. Limited Abstraction
    - Direct HttpClient usage
    - No repository abstractions
    - Limited dependency injection

  4. Session Overuse
    - Heavy reliance on session state
    - Scalability concerns
    - State management complexity

Maintainability Concerns

  1. View Duplication
    - Separate English and Arabic views
    - Difficult to maintain consistency
    - Code duplication between languages

  2. Configuration Management
    - Settings in Web.config
    - No environment-specific configs
    - Hard-coded values in code

  3. Error Handling
    - Inconsistent error handling
    - Generic exception catching
    - Limited error logging

Recommendations

Immediate (Do Now)

  1. Split Large Controllers
    - Break down ServiceProviderController into feature-specific controllers
    - Extract common functionality to base controllers
    - Implement proper separation of concerns

  2. Implement Service Layer
    - Create service classes for business logic
    - Move API calls to service layer
    - Improve testability

  3. Reduce Session Dependency
    - Implement claims-based authentication
    - Use dependency injection for user context
    - Consider stateless authentication (JWT)

Short-term (Do Next)

  1. Improve Localization
    - Implement resource files for translations
    - Share views between languages
    - Use localization helpers

  2. Add Unit Tests
    - Test business logic in services
    - Test controllers with mocked dependencies
    - Test API data access layer

  3. Implement Dependency Injection
    - Use built-in DI container
    - Inject services into controllers
    - Improve testability

Long-term (Plan)

  1. Modernize to .NET Core/6+
    - Better performance
    - Cross-platform support
    - Modern framework features

  2. Implement CQRS Pattern
    - Separate read and write models
    - Improve scalability
    - Better performance

  3. API Gateway Pattern
    - Centralize API calls
    - Better error handling
    - Improved security


Document Version: 1.0
Last Updated: November 2025
Next Review: Quarterly