Category: ROCKEN Documentation

  • Retro Sprint 84

    (синяя звезда) General info

    Liked

    Lacked

    Learned

    Longed for

    • progress and fast development

    • Most identified bugs were fixed

    • finished MVP big tasks

    • actions for Go-Live

    • Release soon

    • many new requirements during the sprint

    • new tracker is not working stable

    • time

    • more UX tasks

    • learned genereting PDF documents (FE)

    • Midjourney

    • passwords in laravel

    • interview with different candidates for the team

    • Good workshop about typography

    • parking additional domain to MS Office 365

    (синяя звезда) What needs to be improved?

  • Elasticsearch: Disaster Recovery Plan

    This document outlines the disaster recovery plan for an Elasticsearch cluster with 3 nodes. It covers procedures to ensure high availability, data protection, and recovery from failure scenarios.

    Before proceeding with the following steps, connect to the target machine or use the machine’s external IP address (if you have the necessary permissions).

    Cluster Architecture Overview

    • Total Nodes: 3 master-eligible nodes.

    • Quorum Requirement: A majority of nodes (2 out of 3) must be available for the cluster to remain functional.

    • Snapshots:

      • Configured for regular backups to a remote location (DigitalOcean Spaces)

      • Configured for regular backups of the virtual machines (droplets)

    Common Failure Scenarios and Recovery Steps

    1. One Node Fails

    Impact:

    • The cluster remains operational.

    • Quorum is maintained (2 out of 3 nodes).

    Recovery Steps:

    1. Identify the failed node using monitoring tools (Kibana, Elastic Monitoring API).

      curl -u "user:password" -X GET "http://localhost:9200/_cat/nodes?v&pretty"
    2. Investigate the issue (droplet failure, network outage,or container crash).

    3. Restore the failed node:

      • Restore Droplet from the snapshot in DigitalOcean (if needed)

      • Restart the Elasticsearch container.

      • Verify the node rejoins the cluster using GET _cat/nodes.

    4. Monitor shard reallocation to ensure data is rebalanced across nodes.

    2. Two Nodes Fail

    Impact:

    • The cluster becomes unavailable.

    • Quorum is lost, and no master node can be elected.

    • Writes and reads are not possible until quorum is restored.

    Recovery Steps:

    1. Determine which nodes are offline.

    2. Check the logs for errors docker logs <container>

    3. Restore at least one of the failed nodes:

      • Restore Droplet from the snapshot in DigitalOcean (if needed)

      • Restart the nodes using docker-compose up.

    4. Once at least 2 nodes are operational, verify the cluster state:

      • Use curl -X GET "http://127.0.0.1:9200/_cluster/health?pretty".

      • Ensure the cluster status moves from red to yellow or green.

    5. Begin the re-indexing process in Elasticsearch:

      • connect to the API container in docker swarm cluster

        
        
      • execute the following commands:

        php artisan scout:import -c 500 Modules\\Profile\\Models\\Profile
        php artisan scout:import -c 500 Modules\\Vacancy\\Models\\Vacancy
        php artisan scout:import -c 500 Modules\\Publication\\Models\\Publication
    6. Investigate and fix the cause of failure to prevent recurrence.

    3. Data Loss or Corruption

    Impact:

    • Data stored in the cluster is partially or fully lost.

    Recovery Steps:

    1. Verify the availability of the latest snapshot:

      • Get the list available snapshots

        curl -u "user:password" -X GET "http://localhost:9200/_cat/snapshots/?v&s=id&pretty"
    2. Restore the data:

    3. Monitor the restoration process:

      • Use GET _cat/recovery to track shard recovery progress.

    4. Begin the re-indexing process in Elasticsearch.


    Restoring Data During Different Scenarios

    1. Restore Data from an Elasticsearch Snapshot

    • Only the Elasticsearch data is restored, without impacting the droplets themselves.

    • This approach is useful for recovering data from logical issues or accidental deletion.

    2. Restore Droplet

    • Restores the entire virtual machine, including Elasticsearch configuration, data, and other services on the droplet.

    • Always restore Elasticsearch snapshots before starting the service on the restored droplet to avoid inconsistencies. But, if the cluster detects that the restored node’s data is outdated, it will re-synchronize the latest data from other nodes to maintain consistency.

    • Suitable for recovering from full droplet corruption.

    3. Create a New Droplet and Add it to the Existing Cluster

    • A new node can be added by copying the docker-compose.yml file from an existing node and updating the .env file.

    • The new node will sync data and settings automatically from the cluster.

    • Useful for scaling the cluster or replacing a permanently failed droplet.

  • Backend Go-Live Checklist


    RT-5995

    Timeline (CET)

    Task

    Ticket

    Assigned to:

    Notes / Instructions

    •  

    16.12.2024 (now)

    Change NS for rocken.ch and set A records to 15 min


    RT-5996

    Roman / Serhii

    •  

    16.12.2024 (now)

    Generate SSL wildcard for *.rocken.ch on DO


    RT-5997

    Roman / Serhii

    •  

    16.12.2024 (now)

    switch off VPN
    Redirect on nginx for OA to point to crm.rocken.ch and talent.rocken.ch


    RT-5994

    Yurich / Dasha

    •  

    23.12.2024 14:00

    [RJ] git cherry-pick before go live


    RT-4532

    Dasha

    •  

    23.12.2024 17:00

    Enable under contstruction page CRM


    RT-5998

    Yurich / Dasha

    •  

    23.12.2024 17:00

    Enable under contstruction page Talent


    RT-5999

    Yurich / Dasha

    •  

    23.12.2024 17:00

    Enable under contstruction page Rocken.Jobs


    RT-6000

    Yurich / Dasha

    •  

    23.12.2024 17:00

    Julia to change roles and user settings


    RT-5530

    Julia / Rico

    •  

    23.12.2024 17:45

    Announce shutdown to Rocken company

    Martin and Julia

    •  

    23.12.2024 18:00

    Change A records for domains for talent.rocken.ch and local.company.rocken.ch

    company.rocken.ch


    RT-6001

    Roman / Serhii

    •  

    23.12.2024 18:01

    Remove read/write for app user on db level and activate nginx redirects talent


    RT-6002

    Roman / Serhii

    •  

    23.12.2024 18:05

    Start backup dump OA prod


    RT-6003

    Roman / Serhii

    •  

    23.12.2024 18:55

    Copy dump to DO rocken (via scp)


    RT-6004

    Roman / Serhii

    •  

    23.12.2024 19:05

    Insert dump on DO rocken


    RT-6005

    Roman / Serhii

    •  

    23.12.2024 19:35

    Start migration


    RT-6006

    Anton / Dasha

    •  

    24.12.2024 10:00

    Check migration and fix if needed


    RT-6007

    Anton / Dasha

    •  

    24.12.2024 15:00

    Check migration and fix if needed

    Anton / Dasha

    •  

    24.12.2024 15:00

    Move finished dump to NA prod


    RT-6008

    Roman / Serhii

    •  

    24.12.2024 16:00 (after migration)

    Run Elastic reindex


    RT-6009

    Yurich / Dasha

    •  

    24.12.2024 16:00 (after migration)

    Sync CRM and Rocken.Jobs


    RT-6010

    Dasha / Yurich

    Sync with Dasha what needs to be done

    •  

    24.12.2024

    Sengrid Webhook settings


    RT-6049

    Yurich / Anton

    •  

    25.12.2024

    After elastic reindex fetch publication count for local chart


    RT-6010

    Dasha / Yurich

    •  

    25.12.2024

    Generate XML feeds and pass new links to external services that we are using after migration


    RT-6048

    Dasha / Yurich

    Sync with Dasha what needs to be done

    25.12.2024

    Turn on the sentry notification in the Slack channel

    Yurich / Dasha

    •  

    25.12.2024

    Remove VPN for NA and whitelist on Sendgrid, Twilio etc.


    RT-6011

    Roman / Serhii

    •  

    25.12.2024

    Enable Email and SMS


    RT-6012

    Yurich / Dasha

    •  

    25.12.2024

    Enable file upload


    RT-6013

    Yurich / Dasha

    •  

    25.12.2024

    Disable under construction pages


    RT-6014

    Dasha and Yurich

    •  

    25.12.2024

    Julia to change roles and user settings


    RT-5530

    Julia / Rico

    •  

    25.12.2024

    NA Regression tests


    RT-6015


    RT-6016


    RT-6017

    Ivan / Viktoriia / Oleksii

    •  

    After 25.12.2024

    Cleanup / remove Old Architecture 3rd Party access and tokens. (e.g. New Relic, Sentry, Twilio etc.)


    RT-6050

    Anton / Yurich

  • Story 1.5.5.6. CRM. Application. Show source of applicant

    Content

    General info

    The Applications page in the CRM displays a list of applicants for various job vacancies. One of the key features of this page is the Source column, which provides information about where the applicant originated. Currently, the source data is gathered from cookies, but this implementation is prone to inaccuracies. The new requirement is to fetch the Source directly from the referral link, ensuring the correct attribution of the applicant’s origin. This enhancement improves data reliability and provides better insights for recruiters.

    User story

    As a CRM user,
    I want to see the accurate source of an applicant in the Source column on the Applications page,
    so that I can understand where the applicant originated and optimize recruitment strategies accordingly.

    Visual design:

    https://www.figma.com/design/I5CXH7H3ICD0vfA1kPbcVf/Rocken-Design?node-id=58547-180231&t=NxR24hy7v0v3zo13-4

     

     

    Acceptance criteria

     

    01

    Scenario: Applicant source is recorded from the link
    Given an applicant accesses the website from external resource
    When apply the vacancy from Rocken jobs
    Then the Source column should display the value from the external website (source)

    image-20241216-081828.png

  • Elasticsearch: Restoring Snapshots

    Before proceeding with the following steps, connect to the target machine or use the machine’s external IP address (if you have the necessary permissions).

    List all Indexes in Elasticsearch:

    curl -u "user:password" -X GET "localhost:9200/_cat/indices?v"

    Important: Elasticsearch cannot restore an open index with the same name. You must delete or rename the existing index before restoring.

    Option 1: Close the Existing Index

    Close the index to allow restoration:

    curl -u "user:password" -X POST "http://localhost:9200/products/_close"

    Option 2: Delete the Existing Index

    Delete the index to make way for the restoration:

    curl -u "user:password" -X DELETE "http://localhost:9200/products"

    List All Available Snapshots

    Verify all snapshots stored in the repository (for quick checks and operational overviews):

    curl -u "user:password" -X GET "http://localhost:9200/_cat/snapshots/test-elasticsearch-space?v&s=id&pretty"

    To retrieve detailed information about a specific snapshot

    curl -u "user:password" -X GET "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_20241211144811?pretty"

    Restore the Snapshot

    Restore a specific index from the snapshot:

    curl -u "user:password" -X POST "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_20241211144811/_restore" -H 'Content-Type: application/json' -d'
    {
      "indices": "products"
    }
    '

    Restore with a New Name

    Restore the snapshot to a new index name:

    curl -u "user:password" -X POST "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_20241211144811/_restore" -H 'Content-Type: application/json' -d'
    {
      "indices": "products",
      "rename_pattern": "products",
      "rename_replacement": "restored_products"
    }
    '

    Verify the Restored Index

    Verify that the restored index is available:

    curl -u "user:password" -X GET "http://localhost:9200/restored_products/_search?pretty"

  • Elasticsearch: Creating Snapshots

    Before proceeding with the following steps, connect to the target machine or use the machine’s external IP address (if you have the necessary permissions).

    Step 1: Get All Items in Elasticsearch

    List all Indexes in Elasticsearch:

    curl -u "user:password" -X GET "localhost:9200/_cat/indices?v"

    List all items in the specific Index:

    curl -u "user:password" -X GET "localhost:9200/products/_search?pretty"

    Step 2: Create a Snapshot

    Create a snapshot of your Elasticsearch data:

    time curl -u "user:password" -X PUT "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_$(date +%Y%m%d%H%M%S)?wait_for_completion=true&pretty" -H 'Content-Type: application/json' -d'
    {
      "indices": "*",
      "ignore_unavailable": true,
      "include_global_state": true
    }
    '

    where:

    • http://127.0.0.1:9200: The Elasticsearch endpoint.

    • /_snapshot/test-elasticsearch-space: Specifies the registered snapshot repository (test-elasticsearch-space).

    • /snapshot_$(date +%Y%m%d%H%M%S): Dynamically generates a unique snapshot name using the current date and time in the format YYYYMMDDHHMMSS. This ensures that snapshots have unique names.

    • ?wait_for_completion=true: Ensures the operation waits until the snapshot creation is complete before returning a response.

    • &pretty: Formats the JSON response for better readability.

    Verifying Snapshots

    List All Available Snapshots

    curl -u "user:password" -X GET "http://localhost:9200/_cat/snapshots/test-elasticsearch-space?v&s=id&pretty"

    Verify all snapshots stored in the repository (for detailed inspection and debugging):

    curl -u "user:password" -X GET "http://localhost:9200/_snapshot/test-elasticsearch-space/_all?pretty"

    To retrieve detailed information about a specific snapshot:

    curl -u "user:password" -X GET "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_20241211144811?pretty"

    Verifying Elasticsearch Data in DigitalOcean Spaces

    1. From the left-hand menu, click Spaces Object Storage under the Manage section.

    2. Select the Space where ElasticSearch snapshots are stored

    3. In the Space, open the directory configured as the base_path in Elasticsearch

    image-20241212-113859.png

    1. Inside the base_path directory, look for snapshot files. These may include:

    • metadata-*.dat files: Metadata for the snapshots.

    • snapshot-*.dat files: The actual snapshot data.

    • index-* files: Index-specific metadata.

    Deleting a Snapshot

    curl -u "user:password" -X DELETE "http://localhost:9200/_snapshot/test-elasticsearch-space/snapshot_20241211144811?pretty"

  • Setting up for QA

    Framework: Playwright

    Language: TypeScript

    IDE: VSCode

    1. Create a GitLab account and add an SSH key:

    1. Register on GitLab

    2. Create an SSH Key on Your Machine.
      macOS:

      ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

      a. Replace "your_email@example.com" with your email address.

      1. Press Enter to save the key in the default location.

      2. Enter a passphrase if required (or press Enter to skip).

      3. Verify the key creation:

        ls ~/.ssh
      4. Add the SSH key to the agent:

        ssh-add ~/.ssh/id_rsa
      5. View the public key:

        cat ~/.ssh/id_rsa.pub
      6. Copy the entire output.

    3. For Windows:
      a. Open Git Bash and run the commands as described for macOS.

    2. Add the SSH Key to GitLab

    1. Log in to your GitLab account.

    2. Navigate to Preferences > SSH Keys.

    3. Click the Add new key.

    4. Paste your copied SSH public key and click Add key.

    3. Install Node.js

    1. Download and install Node.js from the official website.

    2. Verify the installation by running the following commands:

      node -v
      npm -v

    4. Download and set up VSCode:

    1. Download VSCode from the official website.

    2. Install VSCode on your machine.

    3. Create a folder to store the project files.

    4. Open VSCode and select the created folder.

    5. Verify you’re in the correct folder by running:

      ls
    6. Initialize a Node.js project in the terminal:

      npm init

    5. Initialize Git and Clone a Project from GitLab

    1. Initialize Git in the project folder:

      git init
    2. Clone the project repository:

      git@gitlab.cheitgroup.com:talent/tests/end-2-end.git
    3. Install all project dependencies:

      npm install
    4. If Playwright is not installed, run:

      npm init playwright@latest
    5. If errors occur, force installation with:

      npm init playwright@latest --force

    6. Main Git commands:

    Command

    Description

    git checkout [branchName]

    Switch to a specific branch.

    git checkout -b [branchName]

    Create a new branch and switch to it.

    git status

    Check the status of tracked and untracked files in the repository.

    git branch

    List all branches and highlight the current branch.

    git add .

    Stage all changes (modified, new, and deleted files) for the next commit.

    git add [fileName.ts]

    Stage a specific file for the next commit.

    git commit -m "message"

    Create a new commit with a descriptive message.

    git push

    Push committed changes to the remote repository (e.g., GitLab).

    git pull

    Fetch and merge changes from the remote repository into your current branch.

    git rebase [branchName]

    Reapply commits from your branch on top of the specified branch.

    7. Git flow:

             (master)
                │
           git status
                │
                ▼
    git checkout -b feature-branch    // create & switch to feature-branch
                │
                │  (Make your changes)
                │  git add .
                │  git commit -m "BranchName Your Comment"
                │  git push -u origin feature-branch
                ▼
         git checkout master
                │
           git pull         // update local master from remote
                │
           git merge feature-branch // merge happens in GitLab (MR)
                │
           git pull         // fetch any remote changes post-merge
                │
                ▼
           (master updated)
    

  • Story 1.0.2.13. CRM. Head of Recruiting role

    Content

    General info

    The Head of Recruiting role in the CRM system is designed to streamline the management of recruiters and their activities. This role grants the Head of Recruiting access to all candidates and allows them to manage recruiters effectively. The Head of Recruiting can view and edit recruiter information, while other CRM user categories are excluded from their scope.

    User story

    As a Head of Recruiting,
    I want to have access to all candidates and manage recruiters exclusively,
    so that I can ensure efficient recruitment processes and oversee the recruiters’ activities.

    Scheme:

    #

    Acceptance Criteria

    01

    Scenario: Access to candidates
    Given the Head of Recruiting is logged into the CRM
    When they navigate to the Candidates page
    Then they should have access to all candidate profiles, including their details and statuses.

    02

    Scenario: Access to recruiters
    Given the Head of Recruiting is logged into the CRM
    When they navigate to the CRM Users page
    Then only recruiter profiles should be visible.

    03

    Scenario: Managing recruiter information
    Given the Head of Recruiting views a recruiter profile
    When they choose to edit the profile
    Then they should be able to modify all relevant details of the recruiter.

    04

    Scenario: Restricted access to non-recruiter user profiles
    Given the Head of Recruiting is on the CRM Users page
    When they attempt to view or edit a non-recruiter profile
    Then access should be denied, and an appropriate message should be displayed.

    05

    Scenario: Candidate search functionality
    Given the Head of Recruiting is on the Candidates page
    When they search for candidates using filters
    Then the results should display all candidates matching the criteria.

    06

    Scenario: Responsiveness
    Given the Head of Recruiting accesses the CRM on a mobile device
    When they navigate through candidate or recruiter pages
    Then all functionalities should remain accessible and user-friendly on smaller screens.

  • Elasticsearch: Adding DigitalOcean Space as a Snapshot Repository

    When adding a new node to the existing Elasticsearch cluster: It is essential to configure the access and secret keys on the new node.

    Step 1: Add DigitalOcean Spaces Credentials to Elasticsearch Keystore

    Login to each node in the Elasticsearch Cluster and add DigitalOcean Spaces access and secret keys to the Elasticsearch keystore:

    docker exec -it elasticsearch-docker-node-1 /usr/share/elasticsearch/bin/elasticsearch-keystore add s3.client.default.access_key
    docker exec -it elasticsearch-docker-node-1 /usr/share/elasticsearch/bin/elasticsearch-keystore add s3.client.default.secret_key

    Step 2: Restart Elasticsearch

    Restart Elasticsearch for the changes to take effect:

    curl -u "user:password" -X POST "http://localhost:9200/_nodes/reload_secure_settings" -H 'Content-Type: application/json' -d'
    {
       "secure_settings_password":""
    }'

    or

    docker-compose restart

    Ensure that the access and secret keys are added to all Elasticsearch nodes before proceeding to the next step.

    Step 3: Register the Snapshot Repository

    Register the snapshot repository by sending a PUT request:

    curl -u "user:password" -X PUT "http://localhost:9200/_snapshot/test-elasticsearch-space?pretty" -H 'Content-Type: application/json' -d'
    {
        "type": "s3",
        "settings": {
            "bucket": "test-elasticsearch-space",
            "base_path": "elk-snapshots",
            "endpoint" : "fra1.digitaloceanspaces.com"
        }
    }
    '

    where:

    • bucket – name of the storage bucket in DigitalOcean Spaces where snapshots will be stored.

    • base_path – the directory path within the bucket where snapshots will be stored.

    • endpoint – the regional endpoint for DigitalOcean Space

    Expected output:

    {
      "acknowledged" : true
    }

    Step 4: Verify Snapshot Repository

    Check if the repository is registered:

    curl -u "user:password" -X GET "http://localhost:9200/_snapshot?pretty"


    Delete the Snapshot Repository in Elasticsearch

    • all snapshot repositories:

      curl -u "user:password" -X DELETE "http://localhost:9200/_snapshot/*"
    • specific repo:

      curl -u "user:password" -X DELETE "http://localhost:9200/_snapshot/test-elasticsearch-space"

    Troubleshooting

    • verify access and secret key:

      docker exec -it elasticsearch-docker-node-1 /usr/share/elasticsearch/bin/elasticsearch-keystore show s3.client.default.access_key
      docker exec -it elasticsearch-docker-node-1 /usr/share/elasticsearch/bin/elasticsearch-keystore show s3.client.default.secret_key
    • mount a DigitalOcean Space to a Droplet, in order to check permissions and availability:

      • Install s3fs-fuse:

        sudo apt update
        sudo apt install -y s3fs
        s3fs --version
      • Store credentials in a file:

        echo "ACCESS_KEY:SECRET_KEY" > ~/.passwd-s3fs
        chmod 600 ~/.passwd-s3fs
      • Create a Mount Point:

        sudo mkdir /mnt/do-space
      • Mount the Space

        s3fs test-elasticsearch-space /mnt/do-space -o url=https://fra1.digitaloceanspaces.com -o use_path_request_style -o allow_other
      • Verify the Mount

        df -h
        ls /mnt/do-space
        mount
      • command for debugging:

        s3fs test-elasticsearch-space /mnt/do-space -o url=https://fra1.digitaloceanspaces.com -o use_path_request_style -o allow_other -o dbglevel=info -f -o curldbg
  • Story 2.2.9.8. RT. Profile preview. Interview tab. Personal information

    Content

    General info

    The Personal Information Tab within the Interview section of the Rocken Talent (RT) platform provides recruiters with key personal details about the candidate. This section includes marital status, number of children, residency status, and nationality. This information helps recruiters understand the candidate’s personal background in the context of potential employment opportunities.

    User story

    As a recruiter or hiring manager,
    I want to view the candidate’s personal information,
    so that I can better understand their personal background and consider any relevant factors during the recruitment process.

    Visual design:

    https://www.figma.com/design/I5CXH7H3ICD0vfA1kPbcVf/Rocken-Design?node-id=47279-155823&t=RtaKHj5McNNv0wg6-4

     

     

    Acceptance criteria

     

    01

    Scenario: Display Header
    Given I open the Personal Information tab
    When I view the section
    Then I should see the candidate’s name, role, and action buttons such as "Schedule Interview."

    image-20241211-161101.png

    02

    Scenario: View Marital Status
    Given the candidate has provided their marital status
    When I view the corresponding section
    Then I should see the marital status displayed clearly.

    03

    Scenario: View Number of Children
    Given the candidate has specified the number of children
    When I view the Personal Information tab
    Then I should see the number of children displayed.

    04

    Scenario: View Residency Status
    Given the candidate has provided their residency status
    When I view the tab
    Then I should see their residency status displayed (e.g., Swiss Citizen).

    05

    Scenario: View Nationality
    Given the candidate has specified their nationality
    When I view the section
    Then I should see the nationality displayed.

    06

    Scenario: Edit Information
    Given I have editing permissions
    When I click on the "Edit" button for any section
    Then I should be able to modify and save the updated information.

    07

    Scenario: Responsive Design
    Given I access the Personal Information tab on a mobile device
    When I view the tab
    Then all content should adjust responsively for optimal viewing.

    08

    Scenario: Multi-language Support
    Given the platform supports multiple languages
    When I switch the language
    Then all labels and data should display in the selected language.

    09

    Scenario: PDF Download
    Given the candidate’s profile includes personal information
    When I click the "PDF Download" button
    Then the personal information data should be included in the downloaded file.