Skip to content

Mo 228 sept 24 Part 2 FE class based models#2213

Merged
MuhammadKhalilzadeh merged 17 commits intodevelopfrom
mo-228-sept-24-p2-fe-class-based-models
Sep 25, 2025
Merged

Mo 228 sept 24 Part 2 FE class based models#2213
MuhammadKhalilzadeh merged 17 commits intodevelopfrom
mo-228-sept-24-p2-fe-class-based-models

Conversation

@MuhammadKhalilzadeh
Copy link
Copy Markdown
Collaborator

Part 2 FE class based models

Part 2 FE class based models:

  • ProjectFrameworksModel added
  • ProjectScopeModel added
  • ProjectsMembersModel added
  • QuestionModel added
  • RiskModel added
  • RoleModel added
  • SubControlModel added
  • SubscriptionModel added
  • SubtopicModel added
  • TaskAssigneeModel added
  • TaskModel added
  • TierModel added
  • TopicModel added
  • TrainingRegistarModel added
  • VendorModel added
  • VendorRiskModel added
  • VendorsProjectsModel added

Please ensure all items are checked off before requesting a review:

  • I deployed the code locally.
  • I have performed a self-review of my code.
  • I have included the issue # in the PR.
  • I have labelled the PR correctly.
  • The issue I am working on is assigned to me.
  • I have avoided using hardcoded values to ensure scalability and maintain consistency across the application.
  • I have ensured that font sizes, color choices, and other UI elements are referenced from the theme.
  • My pull request is focused and addresses a single, specific feature.

@MuhammadKhalilzadeh MuhammadKhalilzadeh self-assigned this Sep 25, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 25, 2025

Walkthrough

Adds multiple new TypeScript domain model classes under Clients/src/domain/models, each defining typed properties, a constructor that maps input data, and a static factory method for instantiation. No logic beyond data mapping. Models cover projects, assessments, risks, vendors, tasks, subscriptions, tiers, roles, and training.

Changes

Cohort / File(s) Summary
Assessment & Scope Models
Clients/src/domain/models/question/question.model.ts, Clients/src/domain/models/projectScope/projectScope.model.ts, Clients/src/domain/models/topic/topic.model.ts, Clients/src/domain/models/subtopic/subtopic.model.ts
Introduces Question, ProjectScope, Topic, and Subtopic models with typed fields, constructors assigning from data objects, and static factory methods.
Risk & Control Models
Clients/src/domain/models/risks/risk.model.ts, Clients/src/domain/models/vendorRisk/vendorRisk.model.ts, Clients/src/domain/models/subcontrol/subControl.model.ts
Adds Risk, VendorRisk, and SubControl models with extensive typed properties (including unions), constructor-based hydration, and static creators.
Vendor Models
Clients/src/domain/models/vendor/vendor.model.ts, Clients/src/domain/models/vendorsProjects/vendorsProjects.model.ts
Adds Vendor and VendorsProjects models; includes vendor details, statuses, dates, and a join model linking vendors to projects; each with constructor and static factory.
Project Relations
Clients/src/domain/models/projectFramework/projectFrameworks.model.ts, Clients/src/domain/models/projectsMembers/projectsMembers.model.ts
Adds join/association models for project-frameworks and project-members; simple fields, constructor mapping, and static creators.
Tasks
Clients/src/domain/models/task/task.model.ts, Clients/src/domain/models/taskAssignee/taskAssignee.model.ts
Introduces Task and TaskAssignee models; Task references internal TaskPriority/TaskStatus types; both include constructors and static factories.
Subscription & Tier
Clients/src/domain/models/subscription/subscription.model.ts, Clients/src/domain/models/tier/tier.model.ts
Adds Subscription and Tier models; Tier includes exported TierFeatures interface; both provide constructors and static creation methods.
Organization, Roles & Training
Clients/src/domain/models/role/role.model.ts, Clients/src/domain/models/trainingRegistar/trainingRegistar.model.ts
Adds Role and TrainingRegistar models with typed fields, constructor assignment, and static factory methods.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

Poem

I thump my paws—new models bloom,
Fields in rows, constructors zoom.
Static factories hop in line,
Mapping data crisp and fine.
Risks, tasks, vendors—all in sync,
Carrots up! Ship it, wink. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description does not follow the repository’s required template because it uses a custom heading instead of “Describe your changes” and omits the mandatory “Fixes #” section to reference an issue. While it lists the added models and includes a checklist, it fails to include the issue number inline under the proper template heading, making the description incomplete. Update the PR description to match the template by adding the “## Describe your changes” section with a concise purpose statement, inserting a “Fixes #” line to link the relevant issue, and retaining the checklist under the correct heading.
Title Check ❓ Inconclusive The pull request title includes extraneous metadata such as “Mo 228 sept 24” and a date while relying on abbreviations, which obscures the main change and reduces clarity. It does reference adding FE class-based models but the phrasing is ambiguous and not immediately understandable to someone scanning the history. As a result, the title is noisy and does not provide a concise summary of the primary change in a standard format. Consider renaming the title to a clear, concise summary such as “Add front-end class-based models (Part 2)” and remove any date or internal codes to make the change easily discoverable and understandable.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mo-228-sept-24-p2-fe-class-based-models

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MuhammadKhalilzadeh MuhammadKhalilzadeh added enhancement New feature or request frontend Frontend related tasks/issues labels Sep 25, 2025
@MuhammadKhalilzadeh MuhammadKhalilzadeh merged commit 773933a into develop Sep 25, 2025
1 of 2 checks passed
@MuhammadKhalilzadeh MuhammadKhalilzadeh deleted the mo-228-sept-24-p2-fe-class-based-models branch September 25, 2025 13:58
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (16)
Clients/src/domain/models/vendorsProjects/vendorsProjects.model.ts (1)

11-15: LGTM; constructor/factory are straightforward.

No date parsing needed here. Consider aligning factory naming with the convention chosen repo‑wide.

Clients/src/domain/models/role/role.model.ts (1)

16-18: Unify static factory method names across domain models
Rename all static createNewX and static createX to a single convention—for example, drop the New prefix (createVendorProject, createUser, etc.) or switch to fromDTO—and apply it repo-wide.

Clients/src/domain/models/tier/tier.model.ts (2)

12-13: Parse Date fields and relax constructor input type

Treat API date strings safely and accept partial inputs.

Apply:

-  created_at!: Date;
-  updated_at!: Date;
+  created_at?: Date;
+  updated_at?: Date;

-  constructor(data: TierModel) {
+  constructor(data: Partial<TierModel>) {
     this.id = data.id;
     this.name = data.name;
     this.price = data.price;
     this.features = data.features;
-    this.created_at = data.created_at;
-    this.updated_at = data.updated_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;
+    this.updated_at = data.updated_at ? new Date(data.updated_at as any) : undefined;
   }

Also applies to: 15-21


24-26: Standardize factory method naming

Other models mix createX vs createNewX. Pick one convention project‑wide.

Clients/src/domain/models/task/task.model.ts (2)

16-27: Parse Date fields and relax constructor input type

Handle date conversion; allow partials.

-  constructor(data: TaskModel) {
+  constructor(data: Partial<TaskModel>) {
     this.id = data.id;
     this.title = data.title;
     this.description = data.description;
     this.creator_id = data.creator_id;
     this.organization_id = data.organization_id;
-    this.due_date = data.due_date;
+    this.due_date = data.due_date ? new Date(data.due_date as any) : undefined;
     this.priority = data.priority;
     this.status = data.status;
     this.categories = data.categories;
-    this.created_at = data.created_at;
-    this.updated_at = data.updated_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;
+    this.updated_at = data.updated_at ? new Date(data.updated_at as any) : undefined;
   }

30-32: Factory naming consistency

Align with chosen convention (createTask vs createNewTask).

Clients/src/domain/models/projectScope/projectScope.model.ts (2)

15-28: Parse Date field and relax constructor input type

Convert created_at and accept partials.

-  constructor(data: ProjectScopeModel) {
+  constructor(data: Partial<ProjectScopeModel>) {
@@
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;
   }

30-32: Factory method naming inconsistency
Model classes currently mix createX and createNewX (e.g. createNewProjectScope vs createTask). Pick a single convention and rename methods across Clients/src/domain/models for consistency.

Clients/src/domain/models/vendor/vendor.model.ts (1)

21-36: Parse Date fields and relax constructor input type

Convert review_date/created_at and accept partials.

-  constructor(data: VendorModel) {
+  constructor(data: Partial<VendorModel>) {
@@
-    this.review_date = data.review_date;
+    this.review_date = data.review_date ? new Date(data.review_date as any) : undefined as any;
@@
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;
Clients/src/domain/models/question/question.model.ts (1)

1-1: Extract reusable file type; parse created_at; relax constructor input

Reduces duplication and handles dates safely.

+export interface EvidenceFile {
+  id: string;
+  fileName: string;
+  project_id: number;
+  uploaded_by: number;
+  uploaded_time: Date | string;
+}
+
 export class QuestionModel {
@@
-  evidence_files?: {
-    id: string;
-    fileName: string;
-    project_id: number;
-    uploaded_by: number;
-    uploaded_time: Date;
-  }[];
+  evidence_files?: EvidenceFile[];
@@
-  constructor(data: QuestionModel) {
+  constructor(data: Partial<QuestionModel>) {
@@
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;

Also applies to: 11-18, 25-41

Clients/src/domain/models/subcontrol/subControl.model.ts (1)

1-1: Factor file attachment type; parse dates; relax constructor input

DRY up attachment shape and handle dates.

+export interface FileAttachment {
+  id: string;
+  fileName: string;
+  project_id: number;
+  uploaded_by: number;
+  uploaded_time: Date | string;
+}
+
 export class SubControlModel {
@@
-  evidence_files?: {
-    id: string;
-    fileName: string;
-    project_id: number;
-    uploaded_by: number;
-    uploaded_time: Date;
-  }[];
-  feedback_files?: {
-    id: string;
-    fileName: string;
-    project_id: number;
-    uploaded_by: number;
-    uploaded_time: Date;
-  }[];
+  evidence_files?: FileAttachment[];
+  feedback_files?: FileAttachment[];
@@
-  constructor(data: SubControlModel) {
+  constructor(data: Partial<SubControlModel>) {
@@
-    this.due_date = data.due_date;
+    this.due_date = data.due_date ? new Date(data.due_date as any) : undefined;
@@
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;

Also applies to: 15-28, 33-52

Clients/src/domain/models/vendorRisk/vendorRisk.model.ts (1)

21-35: Parse Date field and relax constructor input type

Handle created_at safely; allow partials.

-  constructor(data: VendorRiskModel) {
+  constructor(data: Partial<VendorRiskModel>) {
@@
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at as any) : undefined;
Clients/src/domain/models/risks/risk.model.ts (4)

60-60: Constructor should accept props/DTO, not RiskModel instances.

Accepting RiskModel forces callers to already have a model. Use a props/DTO shape (at minimum Partial) to construct the model.

Apply this diff:

-constructor(data: RiskModel) {
+constructor(data: Partial<RiskModel>) {
-  static createNewRisk(data: RiskModel): RiskModel {
+  static createNewRisk(data: Partial<RiskModel>): RiskModel {

Follow-up: if you make fields optional in the ctor, ensure defaults or validation where needed.

Also applies to: 90-91


66-66: Default risk_category to an empty array.

Prevents consumers from handling undefined arrays.

Apply this diff:

-    this.risk_category = data.risk_category;
+    this.risk_category = data.risk_category ?? [];

5-12: Consolidate literal unions into shared type aliases/enums.

Repeating unions increases drift risk and typos. Define and reuse types like RiskLevel, Likelihood, Severity, MitigationStatus, AiLifecyclePhase.

Example:

export type RiskLevel = "No risk" | "Very low risk" | "Low risk" | "Medium risk" | "High risk" | "Very high risk";
export type Likelihood = "Rare" | "Unlikely" | "Possible" | "Likely" | "Almost Certain";
export type Severity = "Negligible" | "Minor" | "Moderate" | "Major" | "Catastrophic";
export type PostMitigationSeverity = "Negligible" | "Minor" | "Moderate" | "Major" | "Critical";
export type MitigationStatus = "Not Started" | "In Progress" | "Completed" | "On Hold" | "Deferred" | "Canceled" | "Requires review";
export type AiLifecyclePhase =
  | "Problem definition & planning"
  | "Data collection & processing"
  | "Model development & training"
  | "Model validation & testing"
  | "Deployment & integration"
  | "Monitoring & maintenance"
  | "Decommissioning & retirement";

Then reference these aliases on fields.

Also applies to: 18-26, 28-35, 36-41, 46-51, 52-52


55-55: Narrow approval_status to explicit union (line 55) Change approval_status from string to the literal union defined in Clients/src/domain/types/ProjectRisk.ts (or import that type) so it’s restricted to "In Progress" | "Completed" | "On Hold" | "Deferred" | "Canceled" | "Requires review".

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08757cb and ba1af93.

📒 Files selected for processing (17)
  • Clients/src/domain/models/projectFramework/projectFrameworks.model.ts (1 hunks)
  • Clients/src/domain/models/projectScope/projectScope.model.ts (1 hunks)
  • Clients/src/domain/models/projectsMembers/projectsMembers.model.ts (1 hunks)
  • Clients/src/domain/models/question/question.model.ts (1 hunks)
  • Clients/src/domain/models/risks/risk.model.ts (1 hunks)
  • Clients/src/domain/models/role/role.model.ts (1 hunks)
  • Clients/src/domain/models/subcontrol/subControl.model.ts (1 hunks)
  • Clients/src/domain/models/subscription/subscription.model.ts (1 hunks)
  • Clients/src/domain/models/subtopic/subtopic.model.ts (1 hunks)
  • Clients/src/domain/models/task/task.model.ts (1 hunks)
  • Clients/src/domain/models/taskAssignee/taskAssignee.model.ts (1 hunks)
  • Clients/src/domain/models/tier/tier.model.ts (1 hunks)
  • Clients/src/domain/models/topic/topic.model.ts (1 hunks)
  • Clients/src/domain/models/trainingRegistar/trainingRegistar.model.ts (1 hunks)
  • Clients/src/domain/models/vendor/vendor.model.ts (1 hunks)
  • Clients/src/domain/models/vendorRisk/vendorRisk.model.ts (1 hunks)
  • Clients/src/domain/models/vendorsProjects/vendorsProjects.model.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: MuhammadKhalilzadeh
PR: bluewave-labs/verifywise#21
File: Clients/src/presentation/components/ProjectsOverview/index.tsx:8-39
Timestamp: 2024-10-08T15:30:54.617Z
Learning: In the project, mock data should be placed in `Clients/src/presentation/mocks`, e.g., `projects.data.ts`.
🔇 Additional comments (4)
Clients/src/domain/models/projectsMembers/projectsMembers.model.ts (1)

12-16: Factory naming consistency.

createNewProjectsMembers deviates from other files (createRole, createSubtopic, ...). Unify naming (e.g., create or fromDTO) across all models.

See RoleModel comment about standardizing factory names.

Clients/src/domain/models/projectFramework/projectFrameworks.model.ts (1)

12-16: Factory naming consistency.

Align createNewProjectFrameworks with the chosen convention used elsewhere.

See RoleModel comment for repo‑wide naming audit script.

Clients/src/domain/models/task/task.model.ts (1)

1-1: Import verification passed: TaskPriority and TaskStatus are exported enums in Clients/src/domain/interfaces/i.task.ts.

Clients/src/domain/models/risks/risk.model.ts (1)

1-93: Overall model structure LGTM and consistent with the new model pattern.

Constructor mapping and simple factory are clear and consistent with the rest of the PR.

Comment on lines +36 to +41
current_risk_level!:
| "Very Low risk"
| "Low risk"
| "Medium risk"
| "High risk"
| "Very high risk";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix casing mismatch in risk levels (compile-time inconsistency).

"Very Low risk" vs "Very low risk" will cause type mismatches across the app. Align to a single canonical value.

Apply this diff:

   current_risk_level!:
-    | "Very Low risk"
+    | "Very low risk"
     | "Low risk"
     | "Medium risk"
     | "High risk"
     | "Very high risk";
🤖 Prompt for AI Agents
In Clients/src/domain/models/risks/risk.model.ts around lines 36 to 41, the risk
level string literals have inconsistent casing (e.g. "Very Low risk" vs "Very
high risk"); update them to a single canonical format for all entries to avoid
compile-time mismatches — replace the union with consistent Title Case values:
"Very Low Risk", "Low Risk", "Medium Risk", "High Risk", "Very High Risk".

this.review_notes = data.review_notes;
this.mitigation_status = data.mitigation_status;
this.current_risk_level = data.current_risk_level;
this.deadline = data.deadline;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Parse API date strings into Date in the constructor.

Backends generally return ISO strings; assigning directly to Date-typed fields risks Invalid Date or runtime issues when using Date APIs.

Apply this diff:

-    this.deadline = data.deadline;
+    this.deadline =
+      typeof data.deadline === "string" || typeof data.deadline === "number"
+        ? new Date(data.deadline)
+        : data.deadline;

-    this.date_of_assessment = data.date_of_assessment;
+    this.date_of_assessment =
+      typeof data.date_of_assessment === "string" || typeof data.date_of_assessment === "number"
+        ? new Date(data.date_of_assessment)
+        : data.date_of_assessment;

-    this.created_at = data.created_at;
+    this.created_at =
+      data.created_at == null
+        ? undefined
+        : typeof data.created_at === "string" || typeof data.created_at === "number"
+        ? new Date(data.created_at)
+        : data.created_at;

Also applies to: 85-85, 87-87

🤖 Prompt for AI Agents
In Clients/src/domain/models/risks/risk.model.ts around lines 76, 85 and 87 the
constructor assigns API date strings directly to Date-typed fields (e.g.,
this.deadline = data.deadline), which can leave strings or produce Invalid Date
at runtime; update those assignments to parse inputs into Date objects (e.g., if
data.deadline is truthy create new Date(data.deadline) or handle existing Date
instances without re-wrapping) and add minimal input validation (check for
undefined/null and for Invalid Date) before assigning so the class fields are
always real Date objects.

@@ -0,0 +1,19 @@
export class RoleModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Constructor should accept a DTO (not RoleModel) and normalize dates.

Using constructor(data: RoleModel) is tautological and hinders constructing from plain API payloads. Accept a DTO type and coerce created_at to Date. Apply this pattern here (and replicate across the new models).

-export class RoleModel {
+export interface RoleDTO {
+  id?: number;
+  name: string;
+  description: string;
+  is_demo?: boolean;
+  created_at?: string | Date;
+}
+
+export class RoleModel {
   id?: number;
   name!: string;
   description!: string;
   is_demo?: boolean;
   created_at?: Date;

-  constructor(data: RoleModel) {
+  constructor(data: RoleDTO) {
     this.id = data.id;
     this.name = data.name;
     this.description = data.description;
     this.is_demo = data.is_demo;
-    this.created_at = data.created_at;
+    this.created_at = data.created_at
+      ? new Date(data.created_at)
+      : undefined;
   }

-  static createRole(data: RoleModel): RoleModel {
-    return new RoleModel(data);
+  static createRole(data: RoleDTO): RoleModel {
+    return new RoleModel(data);
   }
 }

Note: Consider renaming the factory to fromDTO for clarity and consistency with its purpose.

Also applies to: 6-6, 8-14, 16-18

title!: string;
description!: string;
order_no?: number;
status?: "Waiting" | "In progress" | "Done";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Status literal consistency

Confirm "In progress" matches other modules (Training Registrar uses "In progress" after fix).


🏁 Script executed:

#!/bin/bash
rg -n -C1 -P '"In progress"|"In Progress"' Clients/src

Length of output: 18542


Status literal consistency
subControl.model.ts defines status?: "Waiting" | "In progress" | "Done", but TrainingRegistrar and most components use "In Progress" (capital “P”). Change to "In Progress" to unify across modules.

🤖 Prompt for AI Agents
Clients/src/domain/models/subcontrol/subControl.model.ts around line 6: the
status union uses "In progress" (lowercase p) which conflicts with other modules
that expect "In Progress"; update the union literal to "Waiting" | "In Progress"
| "Done" and run a project-wide search for "In progress" occurrences to update
any mismatched values or tests to the canonical "In Progress" string so typings
and runtime values are consistent.

@@ -0,0 +1,27 @@
export class SubscriptionModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Define SubscriptionDTO, normalize all dates, and type the status.

Current signature requires SubscriptionModel and doesn’t normalize date fields. Also, encode status as a reusable type.

Please confirm backend status literals (is it "canceled" or "cancelled"?). Script to scan the repo:

Proposed changes:

-export class SubscriptionModel {
+export type SubscriptionStatus = "active" | "inactive" | "canceled";
+
+export interface SubscriptionDTO {
+  id?: number;
+  organization_id: number;
+  tier_id: number;
+  stripe_sub_id: string;
+  status: SubscriptionStatus;
+  start_date: string | Date;
+  end_date?: string | Date;
+  created_at: string | Date;
+  updated_at: string | Date;
+}
+
+export class SubscriptionModel {
   id?: number;
   organization_id!: number;
   tier_id!: number;
   stripe_sub_id!: string;
-  status!: "active" | "inactive" | "canceled";
+  status!: SubscriptionStatus;
   start_date!: Date;
   end_date?: Date;
   created_at!: Date;
   updated_at!: Date;

-  constructor(data: SubscriptionModel) {
+  constructor(data: SubscriptionDTO) {
     this.id = data.id;
     this.organization_id = data.organization_id;
     this.tier_id = data.tier_id;
     this.stripe_sub_id = data.stripe_sub_id;
     this.status = data.status;
-    this.start_date = data.start_date;
-    this.end_date = data.end_date;
-    this.created_at = data.created_at;
-    this.updated_at = data.updated_at;
+    this.start_date = new Date(data.start_date);
+    this.end_date = data.end_date ? new Date(data.end_date) : undefined;
+    this.created_at = new Date(data.created_at);
+    this.updated_at = new Date(data.updated_at);
   }

-  static createSubscription(data: SubscriptionModel): SubscriptionModel {
+  static createSubscription(data: SubscriptionDTO): SubscriptionModel {
     return new SubscriptionModel(data);
   }
 }

Also applies to: 2-10, 12-22, 24-26


🏁 Script executed:

#!/bin/bash
# Search for subscription status literals across the repo
rg -nP -C2 '\b(cancelled|canceled|active|inactive)\b' --type-add 'all:*.{ts,tsx,js,py,go,rb,java}'

Length of output: 59


🏁 Script executed:

#!/bin/bash
# Search for subscription status literals across relevant source files
rg -nP -C2 '\b(cancelled|canceled|active|inactive)\b' -g '*.{ts,tsx,js,py,go,rb,java}'

Length of output: 28300


Refactor SubscriptionModel to use SubscriptionDTO and enforce type-safe status

  • Export type SubscriptionStatus = "active" | "inactive" | "canceled" (one ‘l’, matching backend migrations).
  • Add export interface SubscriptionDTO { … } with date fields as string | Date.
  • Change SubscriptionModel to accept SubscriptionDTO in its constructor and convert all date strings via new Date().
🤖 Prompt for AI Agents
In Clients/src/domain/models/subscription/subscription.model.ts around line 1,
refactor the file to export a type alias SubscriptionStatus = "active" |
"inactive" | "canceled" (note single 'l'), add and export an interface
SubscriptionDTO that declares all subscription properties with date fields typed
as string | Date, and update SubscriptionModel so its constructor accepts a
SubscriptionDTO and normalizes any date-string fields by converting them with
new Date(...) to real Date objects while using the SubscriptionStatus type for
the model's status.

@@ -0,0 +1,21 @@
export class SubtopicModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Adopt DTO input and normalize created_at.

Same rationale/pattern as TopicModel.

-export class SubtopicModel {
+export interface SubtopicDTO {
+  id?: number;
+  title: string;
+  order_no?: number;
+  topic_id: number;
+  is_demo?: boolean;
+  created_at?: string | Date;
+}
+
+export class SubtopicModel {
   id?: number;
   title!: string;
   order_no?: number;
   topic_id!: number;
   is_demo?: boolean;
   created_at?: Date;

-  constructor(data: SubtopicModel) {
+  constructor(data: SubtopicDTO) {
     this.id = data.id;
     this.title = data.title;
     this.order_no = data.order_no;
     this.topic_id = data.topic_id;
     this.is_demo = data.is_demo;
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at) : undefined;
   }

-  static createSubtopic(data: SubtopicModel): SubtopicModel {
+  static createSubtopic(data: SubtopicDTO): SubtopicModel {
     return new SubtopicModel(data);
   }
 }

Also applies to: 7-7, 9-16, 18-20

🤖 Prompt for AI Agents
In Clients/src/domain/models/subtopic/subtopic.model.ts around lines 1 and also
affecting 7-7, 9-16, and 18-20, update the class to accept a Subtopic DTO as
input (same shape/pattern used by TopicModel) and normalize the created_at
field: change constructors/factory methods to take the DTO, map DTO properties
to class properties, and convert/validate created_at into a consistent Date (or
ISO string) representation (handle null/undefined and invalid values) before
assigning; update any parameter/return types and tests accordingly to mirror
TopicModel's DTO handling and created_at normalization.

@@ -0,0 +1,15 @@
export class TaskAssigneeModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Accept DTO and coerce assigned_at to Date.

Mirror the DTO+normalization pattern so callers can pass API payloads safely.

-export class TaskAssigneeModel {
+export interface TaskAssigneeDTO {
+  task_id: number;
+  user_id: number;
+  assigned_at?: string | Date;
+}
+
+export class TaskAssigneeModel {
   task_id!: number;
   user_id!: number;
   assigned_at?: Date;

-  constructor(data: TaskAssigneeModel) {
+  constructor(data: TaskAssigneeDTO) {
     this.task_id = data.task_id;
     this.user_id = data.user_id;
-    this.assigned_at = data.assigned_at;
+    this.assigned_at = data.assigned_at
+      ? new Date(data.assigned_at)
+      : undefined;
   }

-  static createTaskAssignee(data: TaskAssigneeModel): TaskAssigneeModel {
+  static createTaskAssignee(data: TaskAssigneeDTO): TaskAssigneeModel {
     return new TaskAssigneeModel(data);
   }
 }

Also applies to: 4-4, 6-10, 12-14

🤖 Prompt for AI Agents
In Clients/src/domain/models/taskAssignee/taskAssignee.model.ts around lines 1-1
(and similarly for ranges 4-4, 6-10, 12-14), the TaskAssigneeModel must accept a
DTO and normalize fields: add a constructor or static fromDTO(dto) that accepts
the API payload, maps DTO properties to the model fields, and coerces
assigned_at into a JS Date (handle string/number/null safely, e.g. new Date(...)
and validate isFinite date). Ensure any optional fields are normalized to
expected types and throw or return a clear error for invalid dates.

@@ -0,0 +1,21 @@
export class TopicModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Use a DTO and coerce created_at to Date (same pattern as others).

Keeps internal type as Date while allowing string inputs from APIs.

-export class TopicModel {
+export interface TopicDTO {
+  id?: number;
+  title: string;
+  order_no?: number;
+  assessment_id: number;
+  is_demo?: boolean;
+  created_at?: string | Date;
+}
+
+export class TopicModel {
   id?: number;
   title!: string;
   order_no?: number;
   assessment_id!: number;
   is_demo?: boolean;
   created_at?: Date;

-  constructor(data: TopicModel) {
+  constructor(data: TopicDTO) {
     this.id = data.id;
     this.title = data.title;
     this.order_no = data.order_no;
     this.assessment_id = data.assessment_id;
     this.is_demo = data.is_demo;
-    this.created_at = data.created_at;
+    this.created_at = data.created_at ? new Date(data.created_at) : undefined;
   }

-  static createTopic(data: TopicModel): TopicModel {
+  static createTopic(data: TopicDTO): TopicModel {
     return new TopicModel(data);
   }
 }

Also applies to: 7-7, 9-16, 18-20

@@ -0,0 +1,27 @@
export class TrainingRegistarModel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Fix class name typo and normalize status literal

Rename Registar → Registrar and use consistent "In progress".

-export class TrainingRegistarModel {
+export class TrainingRegistrarModel {
@@
-  status!: "Planned" | "In Progress" | "Completed";
+  status!: "Planned" | "In progress" | "Completed";
@@
-  static createTrainingRegistar(
-    data: TrainingRegistarModel
-  ): TrainingRegistarModel {
-    return new TrainingRegistarModel(data);
+  static createTrainingRegistrar(
+    data: TrainingRegistrarModel
+  ): TrainingRegistrarModel {
+    return new TrainingRegistrarModel(data);
   }

Run to find and update usages/file name:

Also applies to: 7-7, 22-26


🏁 Script executed:

#!/bin/bash
rg -n -C2 -P '\bTrainingRegistarModel\b|createTrainingRegistar\b|trainingRegistar'

Length of output: 35070


Rename TrainingRegistar→TrainingRegistrar and unify status literal

  • Rename all files, folders, imports, classes and methods from trainingRegistar* to trainingRegistrar* (e.g. TrainingRegistrarModel, createTrainingRegistrar, paths under Clients/src/domain/models and Servers/.../trainingRegistar.*)
  • Change status literal "In Progress""In progress" in client and server model types and validStatuses arrays
  • Update Sequelize model’s tableName (and any migrations/DB references) from "trainingregistar" to "trainingregistrar"
🤖 Prompt for AI Agents
In Clients/src/domain/models/trainingRegistar/trainingRegistar.model.ts around
line 1, the identifier and file path use the misspelled "Registar" and the
status literal casing is inconsistent; rename the class and file path from
TrainingRegistar to TrainingRegistrar (e.g., TrainingRegistrarModel, directory
and file names), update all imports/exports/usages across client and server code
to the new names, change any status string "In Progress" to "In progress" and
update all validStatuses arrays accordingly, and update the Sequelize model
tableName (and any migrations/DB references) from "trainingregistar" to
"trainingregistrar" so names and literals are unified repository-wide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend Frontend related tasks/issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant