Betarena / scores

We are building the first open-source live results and statistics platform with community involvement features for data insertion. The project includes a blockchain component that will allow participants to receive rewards based on their participation and also to stake the future Token of the platform.
GNU General Public License v3.0
18 stars 6 forks source link

Endpoints Sportstacks creation #2271

Closed jonsnowpt closed 2 weeks ago

jonsnowpt commented 2 months ago

1. Get List of Sportstacks by User ID

This function will return a list of Sportstacks for a given user UID from the Hasura database.

Endpoint: GET /sportstacks/:uid

import { queryHasura } from './hasura'; // Helper function to query Hasura

export async function get(req, res) {
  const { uid } = req.params;

  const query = `
    query GetSportstacksByUID($uid: String!) {
      authors(where: {uid: {_eq: $uid}}) {
        id
        uid
        data
        status
        permalink
      }
    }
  `;

  try {
    const { authors } = await queryHasura(query, { uid });
    return res.json(authors);
  } catch (error) {
    console.error('Error fetching sportstacks:', error);
    return res.status(500).json({ message: 'Error fetching sportstacks' });
  }
}

2. Validation Function for Username Availability

This function checks in real-time whether the username is already taken. It queries the authors table for the given username within the data JSONB field.

Endpoint: POST /sportstack/validate-username

import { queryHasura } from './hasura';

export async function post(req, res) {
  const { username } = req.body;

  const query = `
    query ValidateUsername($username: String!) {
      authors(where: {data: {username: {_eq: $username}}}) {
        id
      }
    }
  `;

  try {
    const { authors } = await queryHasura(query, { username });

    // If any result is returned, the username is already taken
    if (authors.length > 0) {
      return res.json({ available: false });
    }

    return res.json({ available: true });
  } catch (error) {
    console.error('Error validating username:', error);
    return res.status(500).json({ message: 'Error validating username' });
  }
}

3. Function to Create a Sportstack

This function inserts a new Sportstack into the authors table, including the user ID, data (with username, avatar, etc.), status, and permalink. The permalink is generated by sanitizing the username (lowercase, replacing spaces with -, and removing non-alphanumeric characters).

Endpoint: POST /sportstack/create

import { queryHasura } from './hasura';

// Helper function to sanitize username and generate permalink
function generatePermalink(username) {
  return username
    .toLowerCase()
    .replace(/\s+/g, '-')   // Replace spaces with hyphens
    .replace(/[^a-z0-9\-]/g, '');  // Remove non-alphanumeric chars
}

export async function post(req, res) {
  const { uid, username, about, avatar, location } = req.body;

  // Validate input (basic validation for demonstration purposes)
  if (!uid || !username) {
    return res.status(400).json({ message: 'UID and username are required' });
  }

  const permalink = generatePermalink(username);
  const creationDate = new Date().toISOString();

  const mutation = `
    mutation CreateSportstack($uid: String!, $data: jsonb!, $status: String!, $permalink: String!) {
      insert_authors_one(object: {
        uid: $uid,
        data: $data,
        status: $status,
        permalink: $permalink
      }) {
        id
      }
    }
  `;

  const data = {
    username,
    about,
    avatar,
    location,
    creation_date: creationDate
  };

  try {
    const result = await queryHasura(mutation, {
      uid,
      data,
      status: 'published',
      permalink
    });
    return res.json({ success: true, sportstackId: result.insert_authors_one.id });
  } catch (error) {
    console.error('Error creating sportstack:', error);
    return res.status(500).json({ message: 'Error creating sportstack' });
  }
}

4. Helper Function: Hasura Query Execution

This helper function interacts with Hasura using its GraphQL endpoint.

hasura.js

import fetch from 'node-fetch';

const HASURA_URL = 'https://your-hasura-instance.com/v1/graphql';
const HASURA_SECRET = 'your-hasura-admin-secret';

export async function queryHasura(query, variables) {
  const response = await fetch(HASURA_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-hasura-admin-secret': HASURA_SECRET
    },
    body: JSON.stringify({ query, variables })
  });

  const data = await response.json();

  if (data.errors) {
    console.error('Hasura query errors:', data.errors);
    throw new Error('Hasura query failed');
  }

  return data.data;
}

Data Example (What Will Be Stored in Hasura)

UID: DxsfWqabJqX3omn2mqoQns7G
data:

{
    "about": "Guias e tutoriais sobre apostas esportivas",
    "avatar": "https://example.com/author-avatar.svg",
    "badges": [],
    "location": "São Paulo",
    "username": "Super Apostas",
    "creation_date": "2024-03-02T14:43:54.035431+00:00"
}

status: published
permalink: super-apostas


Summary of API Endpoints:

  1. List Sportstacks by UID:

    • GET /sportstacks/:uid
    • Retrieves all Sportstacks for a given user based on their uid.
  2. Validate Username Availability:

    • POST /sportstack/validate-username
    • Checks if a given username is available.
  3. Create Sportstack:

    • POST /sportstack/create
    • Creates a new Sportstack with user data, status, and permalink.

This structure ensures that you have the required endpoints to manage Sportstacks for a user, validate usernames in real-time, and create new Sportstacks while ensuring the username is sanitized and stored properly.

ACCEPTANCE CRITERIA: