Backend Development Service For Digital Marketing Obligation and Research

  • Posted 1 month ago
  • Remote

Description

Gig  Overview: The goal of this gig is to Develop a scalable backend microservice for managing digital marketing content  and newsletters calendars, using Node.js + TypeScript and  MySQL with Prisma ORM for scalable and efficient data storage . The service will handle content and newsletter calendars and also market research , storage, scheduling, and distribution, ensuring high performance, security, and maintainability.

Github Repository:

Please, note that the project structure of this application has been established. 

  1. Clone from https://github.com/suburban-fiber-company/Digital_Marketing_Obligation.git

  2. Switch to the development to continue your work and ensure you don’t deviate from it. Do not work outside of these contracts.

Figma design link:

-https://www.figma.com/design/cFE2Rj7W4ESFTedURzQWHx/Digital-Marketing?node-id=0-1&m=dev&t=uynv0LfCpBxU0ygH-1

Scope of Work

The backend microservice will provide endpoints for managing digital marketing content and newsletters calendars and market research guide, ensuring seamless CRUD operations, security, and performance optimization.

Develop endpoints for the following scenarios:

-Create New Content Specification (201 Created)

EndpointPOST /api/v1/content

Description

-The content image will be saved onto a file server (The api documentation will be shared) and will require a url that will be used to display it. Please, note that the file public_url  will be saved into the database.

-Stores the content details in MySQL via Prisma ORM.

Sample Request Body (Form data):

Key: file_name | Value: file.jpeg

Key: content_caption| Value: Lorem Ipsum

Key: hash_tag | Value: #promo #content

Key: content_note | Value: Lorem Ipsum

Key: created_by | Value: John Doe

Key: start_date | Value: 2025-03-25

Key: end_date | Value: 2025-03-25

Field Descriptions:

-file_name (string, required) - The name of the uploaded document

-content_caption (string, required) - Caption for the content

-hash_tag (string, required) - Hashtag(s) associated with the content (e.g., #marketing #trending).

-content_note (string, required) - Detailed notes or body text

-created_by (string, required) - Name of the user creating the content

-strat_date (string, required) - Date the content will run from

-end _date (string, required) - Date the content will  end.

Sample Response :

 {

"status": "success",

“Message”: “Content saved successfully”,

"data": {return saved details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get All Content Schedule For The Month  (200 OK)

Endpoint: GET /api/v1/content

Description: Retrieve all content Scheduled for the month in ASC order. Note that the data will be fed to a calendar.

Sample Response:
{

  "status": "success",

   “message”: “Contents fetched successfully”

  "data": {

    "content": [

      {

        "id": 1,

        "content_caption": "Summer Sale Launch",

        "hash_tag": "#promo #2024",

        "content_note": "Discounts up to 50% on selected items.",

        "public_url": "path/to/file/summer-sale.jpg",

         "created_by": "John Doe",

        "start_date": "2023-03-28T10:00:00Z",

        "end_date": "2023-03-28T10:00:00Z",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

      },

      {

        "id": "2",

        "content_caption": "New Product Announcement",

        "hash_tag": "#tech #innovation",

        "content_note": "Introducing our latest AI-powered tool.",

        "public_url": "path/to/file/summer-sale.jpg",

         "created_by": "John Doe",

        "start_date": "2023-03-28T10:00:00Z",

        "end_date": "2023-03-28T10:00:00Z",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

      }

    ],  

  }

}

 

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get Single content By Id

Endpoint: GET /api/v1/content/:id

-Fetches details of a single content by its ID.

Description: Retrieve detailed information about a specific content.

Sample Response:
{

  "status": "success",

   “message”: “Content fetched successfully”

  "data": {

        "id": 1,

        "content_caption": "Summer Sale Launch",

        "hash_tag": "#promo #2024",

        "content_note": "Discounts up to 50% on selected items.",

        "public_url": "path/to/file/summer-sale.jpg",

          "created_by": "John Doe",

        "start_date": "2023-03-28T10:00:00Z",

        "end_date": "2023-03-28T10:00:00Z",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

      }

}

     Error Response (500 Internal Server Error):

{

  "status": "error",

  "message": "Sorry, unable to complete the operation. Please, try again"

}

-Update Content (200 OK)

Endpoint: PATCH /api/v1/content/:id/update
Description: Updates a single content

Request Body (form-data):

Key: file_name | Value: file.jpeg

Key: content_caption| Value: Lorem Ipsum

Key: hash_tag | Value: #content #2024

Key: created_by| Value: John Doe

Key: content_note | Value: Lorem Ipsum

Key: start_date | Value: 2025-03-25

Key: end_date | Value: 2025-03-25

Sample Response:

 {

"status": "success",

“Message”: “Content updated successfully”,

"data": {return updated content details details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Create New Newsletter Specification (201 Created)

EndpointPOST /api/v1/newsletters

Description

-The newsletter image will be saved onto a file server  (The api documentation will be shared) and will require a url that will be used to display it. Please, note that the public_url  will be saved into the database.

-Stores the content details in MySQL via Prisma ORM.

Sample Request Body (Form data):

Key: file_name | Value: file.jpeg

Key: newsletter_caption| Value: Lorem Ipsum

Key: hash_tag | Value: #promo ~2024

Key: newsletter_note | Value: Lorem Ipsum

Key: created_by | Value: John Doe

Field Descriptions:

-file_name (string, required) - The name of the uploaded document

-newsletter_caption (string, required) - Caption for the newsletter

-hash_tag (string, required) - Hashtag(s) associated with the newsletter (e.g., #marketing #trending).

-newsletter_note (string, required) - Detailed notes or body text

-created_by (string, required) - Name of the user creating the newsletter

Sample Response :

 {

"status": "success",

“Message”: “Newsletter updated successfully”,

"data": {return saved details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get All Newsletters Schedule For The Month  (200 OK)

Endpoint: GET /api/v1/newsletter

Description: Retrieve all newsletter in DESC order

Sample Response:
{

  "status": "success",

 "message": "Newsletters Fetched Successfully",

  "data": {

    "newsletters": [

      {

        "id": 2,

        "newsletter_caption": "Summer Sale Launch",

        "hash_tag": "#promo #2024",

        "newsletter_note": "Discounts up to 50% on selected items.",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

 

      },

      {

        "id": "1",

        "newsletter_caption": "New Product Announcement",

        "hash_tag": "#tech #innovation",

        "newsletter_note": "Introducing our latest AI-powered tool.",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

      }

    ],  

  }

}

 

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get Single newsletter By Id

Endpoint: GET /api/v1/newsletter/:id

-Fetches details of a single newsletter by its ID.

Description: Retrieve detailed information about a specific newsletter.

Sample Response:
{

  "status": "success",

  "data": {

        "id": 1,

        "newsletter_caption": "Summer Sale Launch",

        "hash_tag": "#promo #2024",

        "newsletter_note": "Discounts up to 50% on selected items.",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

         "created_at": "2025-02-21T10:00:00Z", 

          "updated_at": "2025-02-21T10:00:00Z"

      }

}

     Error Response (500 Internal Server Error):

{

  "status": "error",

  "message": "Sorry, unable to complete the operation. Please, try again"

}

-Update Newsletter (200 OK)

Endpoint: PATCH /api/v1/newsletters/:id
Description: Updates a single newsletter

Request Body (form-data):

Key: file_name | Value: file.jpeg

Key: newsletter_caption| Value: Lorem Ipsum

Key: hash_tag | Value: #promo ~2024

Key: newsletter_note | Value: Lorem Ipsum

Key: created_by | Value: John Doe

 

Sample Response:

 {

"status": "success",

“Message”: “Newsletter updated successfully”,

"data": {return updated newsletter details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Create New  Market Research Guide (201 Created)

EndpointPOST /api/v1/market-research

Description

-The market research file will be saved onto a file server and will require a url that will be used to display it. Please, note that the public_url will be saved into the database.

-Stores the content details in MySQL via Prisma ORM.

Sample Request Body (Form data):

Key: title | Value: Title

Key: problem_statment | Value: Lorem Ipsum

Key: market_size | Value: 20

Key: file_name | Value: file.pdf

Key: update_note | Value: Lorem Ipsum

Key: created_by | Value: John Doe

Field Descriptions:

-title (string, required) - The title of the research

-problem_statement (string, required) - Problem statement of the research

-market_size (integer, required) - Size of the market

-update_note (string, required) - Detailed update  notes or body text

-created_by (string, required) - Name of the user creating the market research guide

-file_name (string, required) - Name of file to be uploaded

Sample Response :

 {

"status": "success",

“Message”: “Market research guide saved successfully”,

"data": {return saved details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get All Market Research Guide  (200 OK)

Endpoint: GET /api/v1/market-research

Description: Retrieve all market research in DESC order with optional filtering by title and market_size 

Query Parameters:

-search: (optional) keyword search.

-title: (optional) filter by title.

-market_size: (optional) filter by market_size.

-sort_by: (optional) created_at (asc/desc).

 

Sample Response:
{

  "status": "success",

 "message": "Market Research Fetched Successfully",

  "data": {

    "market_reearch": [

      {

        "id": 1,

        "title": "Summer Sale Launch",

        "problem_statement": "Summer Sale Launch",

        "market_size": 500,

        "update_note": "Lorem Ipsum",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

        "created_at": "2025-02-21T10:00:00Z",

"updated_at": "2025-02-21T10:00:00Z"

      },

      {

        "id": 1,

        "title": "Summer Sale Launch",

        "problem_statement": "Summer Sale Launch",

        "market_size": 500,

        "update_note": "Lorem Ipsum",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

         "created_at": "2025-02-21T10:00:00Z": 

          "updated_at": "2025-02-21T10:00:00Z"

      }

    ], 

  "pagination": {

"total": 8,

"current": 1,

"from": 1,

"to": 8,

"pages": 1

  }

}

 

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

-Get Single Market Research By Id

Endpoint: GET /api/v1/market-research/:id

-Fetches details of a single market-research by its ID.

Description: Retrieve detailed information about a specific market-research.

Sample Response:
{

  "status": "success",

  "data":  {

        "id": 1,

        "title": "Summer Sale Launch",

        "problem_statement": "Summer Sale Launch",

        "market_size": 500,

        "update_note": "Lorem Ipsum",

        "public_url": "path/to/file/summer-sale.jpg",

        "created_by": "John Doe",

      }

}

     Error Response (500 Internal Server Error):

{

  "status": "error",

  "message": "Sorry, unable to complete the operation. Please, try again"

}

}

  • Update Market Research (200 OK)

Endpoint: PATCH /api/v1/market-research/:id
Description: Updates a single market research

Request Body (form-data):

Key: title | Value: Title

Key: problem_statment | Value: Lorem Ipsum

Key: market_size | Value: 20

Key: file_name | Value: file.pdf

Key: update_note | Value: Lorem Ipsum

Key: created_by | Value: 2025-03-25



Sample Response:

 {

"status": "success",

“Message”: “Newsletter updated successfully”,

"data": {return updated market research details }

Error Response (500 Internal Server Error):

{

"status": "error",

"message": "return appropriate error message"

}

 

Backend Developer

Proficiency in Node.js/TypeScript language for backend development.

Strong understanding of RESTful API development and integration.

Skilled in Prisma ORM (MySQL) database optimization for performance and scalability.

Required Skills:

Strong backend development using Node.js/TypeScript

Expertise in MySQL database design and architecture.

Knowledge of API security best practices, including data validation and input sanitization.

Must be familiar with the use of Joi for request validations

Strong knowledge of Joi Library for request validation

Software/Design Requirements:

Framework: Node.js/Typescript.

Database: Prisma ORM, MySQL for relational data storage.

Authentication: API Token validation

API Documentation: Swagger for endpoint documentation.


Breakdown of Common API status codes

Please ensure all of the status codes are properly handled for seamlessly frontend integration

400 Bad Request – The server cannot process the request due to client error (e.g., invalid JSON, missing parameters).

401 Unauthorized – The request lacks valid authentication credentials (e.g., missing or invalid token).

404 Not Found – The requested resource does not exist on the server.

422 Unprocessable Entity – The request is well-formed but contains invalid data (e.g., validation errors).

500 Internal Server Error – A generic server-side error, often due to unexpected failures in processing.

 

Expectations

As a Techo chosen to participate in this gig, we have some expectations.

-Timely Completion: complete each gig within the given timeframe. If the gig has not been completed within this frame, the project will be re-assigned.

-Communication: Stay in touch with the Community Manager for guidance, support and feedback throughout the project. This can be done through the chat box in the My Gigs section underneath the gig description.

-Work-Ethic Alignment: Make a concerted effort to comply with our standards.

-It is very key that Techo pays very attentions to details so as to avoid disqualification or re-assigning of the gig

-Where the project structure has been defined, it is very important that the Techo does not deviate from the established structure

Skills required

Gigs you may like

Fixed price gig
  • 5 months ago
  • Remote
  • Intermediate
  • 1 Freelancer
Gig Budget

₦10,000.00 - ₦10,000.00

Fixed price gig
  • 1 month ago
  • Remote
  • Intermediate
  • 1 Freelancer
Gig Budget

₦45,000.00 - ₦55,000.00

Fixed price gig
  • 2 weeks ago
  • Remote
  • Intermediate
  • 1 Freelancer
Gig Budget

₦30,000.00 - ₦35,000.00