Skip to content

Users Domain

The Users domain manages user accounts, authentication, authorization, identity verification (KYC), and user portfolios. It is the foundation of the 2KRIKA platform, providing the user management infrastructure for customers, sellers, and administrators.

Overview

The Users domain encompasses:

  • User accounts – Registration, profiles, authentication
  • Roles and permissions – RBAC (Role-Based Access Control)
  • Identity verification – KYC (Know Your Customer) process
  • User portfolios – Skills, projects, experience, education

Entities

User Entity

The core entity representing a platform user.

// domain/user/user.entity.ts
export class User {
  id: string;
  fullName: string;
  email: string;
  passwordHash: string;
  username: string;
  isActive: boolean;
  isStaff: boolean;
  isSuperuser: boolean;
  isKYCVerified: boolean;
  title: string;
  description: string;
  notes: string;
  lastLogin: Date | null;
  createdAt: Date;
  updatedAt: Date;
  private permissions?: Permission[];

  static create(
    id: string,
    fullName: string,
    username: string,
    email: string,
    passwordHash: string,
    // ... other parameters
  ): User

  // Business rules
  activate(): void
  deactivate(): void
  approveKyc(): void
  cancelKYC(): void
  hasPermission(permission: Permission): boolean
  setPermissions(permissions: Permission[]): void
  getPermissions(): Permission[] | undefined
}

Key properties: - id – Unique identifier (CUID) - email – Unique email address - username – Unique username - passwordHash – Bcrypt hashed password - isActive – Account activation status - isStaff – Staff access flag - isSuperuser – Superuser access (all permissions) - isKYCVerified – KYC verification status

Business rules: - activate() / deactivate() – Control account status - approveKyc() / cancelKYC() – Manage KYC verification - hasPermission() – Check authorization (superusers have all permissions)

Role Entity

Predefined roles with associated permissions.

// domain/user/role.entity.ts
export class Role {
  id: string;
  name: string;
  permissions: Permission[];

  static readonly ADMIN: Role
  static readonly CUSTOMER: Role
  static readonly SELLER: Role

  hasPermission(permission: Permission): boolean
  static all(): Role[]
  static get(id: string): Role | undefined
  static getByName(name: string): Role | undefined
}

Predefined roles:

  1. ADMIN
  2. Full platform administration
  3. User management
  4. Category and service moderation
  5. KYC approval/rejection
  6. Withdraw and refund processing
  7. Access to all administrative features

  8. CUSTOMER

  9. Browse services
  10. Place orders
  11. Submit KYC
  12. Participate in chats
  13. View own data

  14. SELLER

  15. Create and manage services
  16. Fulfill orders
  17. Initiate withdrawals
  18. View own sales data
  19. Participate in chats

Permission Value Object

Fine-grained permissions enum.

// domain/user/permission.vo.ts
export enum Permission {
  VIEW_ME = "view_me",
  CREATE_USER = "create_user",
  DELETE_USER = "delete_user",
  VIEW_USERS = "view_users",
  ACTIVATE_USERS = "activate_users",
  DEACTIVATE_USERS = "deactivate_users",

  CREATE_SERVICE = "create_service",
  UPDATE_SERVICE = "update_service",
  DELETE_SERVICE = "delete_service",
  APPROVE_SERVICE = "approve_service",
  REJECT_SERVICE = "reject_service",
  SUSPEND_SERVICE = "suspend_service",

  CREATE_CATEGORY = "create_category",
  UPDATE_CATEGORY = "update_category",
  DELETE_CATEGORY = "delete_category",

  SUBMIT_KYC = "submit_kyc",
  APPROVE_KYC = "approve_kyc",
  REJECT_KYC = "reject_kyc",

  PASS_ORDER = "pass_order",
  LIST_ORDERS = "list_orders",
  VIEW_ORDER = "view_order",

  INITIATE_WITHDRAW = "initiate_withdraw",
  COMPLETE_WITHDRAW = "complete_withdraw",
  VIEW_REFUND = "view_refund",
  COMPLETE_REFUND = "complete_refund",

  // ... many more permissions
}

Identity Entity

KYC identity information for users.

// domain/user/identiy.entity.ts
export class Identity {
  id: string;
  firstName: string;
  lastName: string;
  birthDate: Date;
  nationality: string;
  businessType: BusinessType; // 'individual' | 'company'
  business: BusinessDetails | null;
  addressLine1: string;
  addressLine2: string;
  city: string;
  state: string;
  postalCode: string;
  country: string;
  phoneNumber: string;
  idDocumentType: IdDocumentType; // 'passport' | 'id_card' | 'driver_license'
  idDocumentId: string;
  userId: string;
  status: IdentityStatus; // 'draft' | 'pending' | 'approved'
  KYCValidationDate: Date | null;
  createdAt: Date;
  updatedAt: Date;

  canBeSubmitted(): boolean
  canBeApproved(): boolean
  getMissingRequiredFields(): string[]
  approve(): void
  submit(): void
}

KYC workflow: 1. Draft – User fills identity information 2. Pending – User submits for review 3. Approved – Admin approves, user becomes KYC verified

Portfolio Entities

User portfolio components for sellers.

// domain/user/portfolio.entities.ts

class Skill {
  id: string;
  userId: string;
  name: string;
}

class Project {
  id: string;
  userId: string;
  title: string;
  description: string;
  bannerId: string | null;
  serviceId: string | null;
}

class Experience {
  id: string;
  userId: string;
  companyName: string;
  position: string;
  startDate: Date;
  endDate: Date | null;
  description: string;
}

class Education {
  id: string;
  userId: string;
  institutionName: string;
  degree: string;
  deliveryDate: Date;
}

Repositories

UserRepository

// domain/user/user.repository.ts
export abstract class UserRepository extends AbstractRepository<User, string, UserQueryPolicy> {
  abstract getKYCValidationDate(userId: string): Promise<Date | null>;
  abstract approveKyc(id: string, opts?: any): Promise<void>;
  abstract filterByIds(ids: string[]): Promise<User[]>;
}

export class UserQueryPolicy extends Pagination {
  isActive?: boolean;
  isKYCVerified?: boolean;
  search?: string; // Search in fullName or email
  roles?: string[]; // Filter by roles
  orderBy?: string[]; // e.g., ["createdAt"] or ["-createdAt"]
}

Key operations: - add() – Create new user - get() – Get by ID - getBy() – Get by criteria (email, username) - all() – List with filters (search, roles, KYC status) - approveKyc() – Mark user as KYC verified - filterByIds() – Batch fetch users

IdentityRepository

// domain/user/identity.repository.ts
export abstract class IdentityRepository extends AbstractRepository<Identity> {
  abstract getByUserId(userId: string): Promise<Identity>;
  abstract listValidationRequests(filters: any): Promise<Paginated<Identity>>;
}

UserRoleRepository

// domain/user/userrole.repository.ts
export abstract class UserRoleRepository {
  abstract assignRole(userId: string, roleId: string): Promise<void>;
  abstract removeRole(userId: string, roleId: string): Promise<void>;
  abstract getUserRoles(userId: string): Promise<Role[]>;
  abstract getAllPermissions(user: User): Promise<void>;
}

CompetencyRepository

Manages user portfolio items (skills, projects, experience, education).

// domain/user/portfolio.repository.ts
export abstract class CompetencyRepository {
  abstract addSkill(skill: Skill): Promise<Skill>;
  abstract addProject(project: Project): Promise<Project>;
  abstract addExperience(experience: Experience): Promise<Experience>;
  abstract addEducation(education: Education): Promise<Education>;

  abstract getUserSkills(userId: string): Promise<Skill[]>;
  abstract getUserProjects(userId: string): Promise<Project[]>;
  abstract getUserExperience(userId: string): Promise<Experience[]>;
  abstract getUserEducation(userId: string): Promise<Education[]>;

  abstract deleteSkill(id: string): Promise<void>;
  abstract deleteProject(id: string): Promise<void>;
  abstract deleteExperience(id: string): Promise<void>;
  abstract deleteEducation(id: string): Promise<void>;
}

Business Rules

User Registration

  1. Email uniqueness – Enforced by database constraint
  2. Username uniqueness – Enforced by database constraint
  3. Password strength – Minimum 8 characters (validated in application layer)
  4. Default state – New users are inactive until they activate via email
  5. Automatic username generation – If not provided, generated from full name

User Activation

  1. Users receive activation email with token
  2. Clicking link activates account (isActive = true)
  3. Only active users can log in

KYC Verification

  1. Draft state – User can edit identity information
  2. Submission – Must have all required fields
  3. Pending review – Admin reviews documents
  4. Approval – Admin approves, user becomes isKYCVerified = true
  5. Business types:
  6. Individual – Only personal details required
  7. Company – Requires business name and details

Authorization

  1. Superusers – Have all permissions
  2. Role-based – Permissions assigned via roles
  3. Permission checkinguser.hasPermission(Permission.XXX)
  4. Guards – Web layer enforces permissions on endpoints

User Deactivation

  1. Admin can deactivate users
  2. Deactivated users cannot log in
  3. User's services are also deactivated
  4. Existing orders continue normally

Use Cases

User Management

  • Create user – Register new account
  • Activate user – Email verification
  • Update profile – Edit name, title, description
  • Upload profile picture – Attach image
  • Deactivate user – Admin action
  • List users – With filters (search, role, KYC status)
  • Get user details – View profile

KYC Management

  • Create identity – Initialize KYC profile
  • Update identity – Edit KYC information
  • Submit KYC – Request admin review
  • List KYC requests – Admin view pending verifications
  • Approve KYC – Admin approves verification
  • Reject KYC – Admin rejects with reason

Portfolio Management

  • Add skill – Add skill to portfolio
  • Add project – Add project with banner
  • Add experience – Add work experience
  • Add education – Add education record
  • List portfolio – Get all user portfolio items
  • Delete portfolio item – Remove from portfolio

Integration Points

With Orders Domain

  • Order.customerId references User.id
  • Order.sellerId references User.id
  • Users can view their orders (as customer or seller)

With Services Domain

  • Service.ownerId references User.id
  • Only KYC verified users can create services (sellers)

With Accounts Domain

  • Each user has one Account for balance management
  • Accounts reference User.id

With Notifications

  • Users receive email notifications
  • Notifications reference User.id

Key Workflows

User Registration Flow

1. User submits registration form
2. Validate email/username uniqueness
3. Hash password
4. Create User entity (isActive = false)
5. Assign CUSTOMER role by default
6. Send activation email
7. User clicks activation link
8. User.activate()
9. User can log in

KYC Verification Flow

1. User creates Identity (status = draft)
2. User uploads ID documents
3. User fills all required fields
4. User submits Identity (status = pending)
5. Admin reviews submission
6. Admin approves Identity (status = approved)
7. User.approveKyc()
8. User can create services (if seller role)

Permission Check Flow

1. Request arrives at endpoint
2. AuthGuard extracts JWT token
3. Load User from database
4. Load User roles and permissions
5. Check user.hasPermission(requiredPermission)
6. Allow or deny request

Data Model

┌─────────────┐
│    User     │
├─────────────┤
│ id          │◄────┐
│ email       │     │
│ username    │     │
│ passwordHash│     │
│ isActive    │     │
│ isKYCVerified│    │
└─────────────┘     │
┌─────────────┐     │
│  Identity   │     │
├─────────────┤     │
│ id          │     │
│ userId      │─────┘
│ firstName   │
│ lastName    │
│ status      │
└─────────────┘

┌─────────────┐     ┌─────────────┐
│  UserRole   │────►│    Role     │
├─────────────┤     ├─────────────┤
│ userId      │     │ id          │
│ roleId      │     │ name        │
└─────────────┘     │ permissions │
                    └─────────────┘

┌─────────────┐
│ Portfolio   │
├─────────────┤
│ Skill       │
│ Project     │
│ Experience  │
│ Education   │
└─────────────┘

Best Practices

✅ Do

  • Hash passwords – Use bcrypt, never store plain text
  • Validate uniqueness – Email and username must be unique
  • Check permissions – Always validate authorization
  • Use KYC status – Restrict sensitive operations to verified users
  • Audit changes – Track who modified user data

❌ Don't

  • Don't expose passwordHash – Never include in DTOs
  • Don't bypass activation – Users must verify email
  • Don't skip permission checks – Always validate authorization
  • Don't allow self-promotion – Users can't make themselves staff/superuser
  • Don't delete users – Deactivate instead to preserve history

Summary

The Users domain provides:

  • User account management with email verification
  • Role-based access control with fine-grained permissions
  • KYC verification for identity validation
  • User portfolios for seller profiles
  • Flexible authorization supporting multiple roles per user

This domain is foundational—all other domains depend on User for authentication and authorization.