{"id":15832049,"url":"https://github.com/victor-lis/studyplus-back-end","last_synced_at":"2026-03-15T00:54:28.989Z","repository":{"id":214798550,"uuid":"693653124","full_name":"Victor-Lis/StudyPlus-Back-End","owner":"Victor-Lis","description":null,"archived":false,"fork":false,"pushed_at":"2024-01-07T19:39:40.000Z","size":74,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-23T12:44:29.555Z","etag":null,"topics":["api","localdb","node","prisma-schema","sqlite"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Victor-Lis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-19T12:58:39.000Z","updated_at":"2024-02-19T01:01:59.000Z","dependencies_parsed_at":"2024-01-07T20:43:27.268Z","dependency_job_id":"89280d7b-d5ca-4ec3-87ce-b22335557733","html_url":"https://github.com/Victor-Lis/StudyPlus-Back-End","commit_stats":null,"previous_names":["victor-lis/studyplus-back-end"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Victor-Lis/StudyPlus-Back-End","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Victor-Lis%2FStudyPlus-Back-End","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Victor-Lis%2FStudyPlus-Back-End/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Victor-Lis%2FStudyPlus-Back-End/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Victor-Lis%2FStudyPlus-Back-End/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Victor-Lis","download_url":"https://codeload.github.com/Victor-Lis/StudyPlus-Back-End/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Victor-Lis%2FStudyPlus-Back-End/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274010098,"owners_count":25206763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","localdb","node","prisma-schema","sqlite"],"created_at":"2024-10-05T12:40:31.664Z","updated_at":"2026-03-15T00:54:23.953Z","avatar_url":"https://github.com/Victor-Lis.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Study+ BackEnd\n\n[Study+ FrontEnd](https://github.com/Victor-Lis/StudyPlus-Front-End)\n\nEsse é um projeto que ainda tenho muitos planos, essa ainda é a versão 1, mas já tenho em mente features futuras. Falando dele em si, eu já tinha esse projeto em mente há alguns meses, conversava bastante sobre a ideia com o [@Vinicius-Buava](https://github.com/Vinicius-B-Leite), além de já ter feito uma \"versão anterior\" desse projeto, mas ele estava bem simples e foi um dos meus primeiros projetos em Node, então existiam muitas melhoras a serem feitas.\n\nO projeto consiste em um sistema para ajudar a organizar seu tempo disposto em atividades mais focadas como estudo, sendo possível inclusive programar tarefas futuras(dentro do prazo de uma semana) para ajudar na organização. \n\nÉ possível criar as próprias \"categorias\", que serão atribuidas as atividades.\n## Desafios\n\n- Planejamento do Banco de Dados;\n- Criação das rotas necessárias para cada tabela;\n- Relacionamento entre as tabelas;\n- Criação de um CRUD para cada tabela necessária.\n\n#### Verificação de condições\n- Where, verificar quais valores eram requeridos em um where;\n- Verificar se uma tarefa estava completa ou não ao ser apagada, para verificar se era necessário descontar as horas daquela atividade;\n- Verificar se a semana referente ao dia atual acabou ou não.\n## Aprendizados\n\nPor final aprendi algumas coisas interessantes como: \n### Criação e Importação das Rotas\n#### Criação\n\n- Week\n```js\nconst express = require(\"express\")\nconst weekRouter = express.Router()\nconst { PrismaClient } = require('@prisma/client')\nconst prisma = new PrismaClient();\n\nweekRouter.get('/week', {...})\nweekRouter.post('/week/create', {...})\nweekRouter.post('/week/delete', {...})\n\nmodule.exports = weekRouter\n```\n\n- Task\n```js\nconst express = require(\"express\")\nconst taskRouter = express.Router()\nconst { PrismaClient } = require('@prisma/client')\nconst prisma = new PrismaClient();\n\ntaskRouter.get('/task', {...})\ntaskRouter.post('/task/create', {...})\ntaskRouter.post('/task/update', {...})\ntaskRouter.post('/task/completed', {...})\ntaskRouter.post('/task/delete', {...})\n\nmodule.exports = taskRouter\n```\n\n- Categorie\n```js\nconst express = require(\"express\")\nconst categorieRouter = express.Router()\nconst { PrismaClient } = require('@prisma/client')\nconst prisma = new PrismaClient();\n\ncategorieRouter.get('/categorie', {...})\ncategorieRouter.post('/categorie/create', {...})\ncategorieRouter.post('/categorie/update', {...})\ncategorieRouter.post('/categorie/delete', {...})\n\nmodule.exports = categorieRouter\n```\n\n- Prompt (Ainda em desenvolvimento no Front-End)\n```js\nconst express = require(\"express\")\nconst promptRouter = express.Router()\nconst { PrismaClient } = require('@prisma/client')\nconst prisma = new PrismaClient();\n\npromptRouter.get('/prompt', {...})\npromptRouter.post('/prompt/create', {...})\npromptRouter.post('/prompt/update', {...})\npromptRouter.post('/prompt/completed', {...})\npromptRouter.post('/prompt/delete', {...})\n\nmodule.exports = promptRouter\n```\n#### Importação\n```js\nconst express = require('express');\nconst app = express();\n\nconst cors = require('cors')\napp.use(cors());\n\nconst bodyParser = require('body-parser');\napp.use(bodyParser.json())\n\nconst weekRouter = require('./routes/Week')\napp.use(weekRouter)\n\nconst categorieRouter = require('./routes/Categorie')\napp.use(categorieRouter)\n\nconst taskRouter = require('./routes/Task')\napp.use(taskRouter)\n\nconst promptRouter = require('./routes/Prompt')\napp.use(promptRouter)\n\nconst port = process.env.PORT || 4000\n\napp.listen(port, () =\u003e {\n  console.log(port == 4000 ? `Server is running on http://localhost:${port}` : `Server is running on ${port}`);\n});\n```\n\n### Necessidades Específicas\n#### Tabela Week\nAo criar a Week eu preciso atribuir os dias a ela, logo eu rodo um for() para adicionar os 7 dias da semana.\n```js\nasync function createWeek() {\n    let days = []\n    let date = new Date()\n    let initialDay = date.getDate()\n    //`${year}-${month}-${day}T00:00:00.000Z`\n    let week = await prisma.week.create({})\n\n    let daysNames = {\n        0: \"Domingo\",\n        1: \"Segunda\",\n        2: \"Terça\",\n        3: \"Quarta\",\n        4: \"Quinta\",\n        5: \"Sexta\",\n        6: \"Sábado\",\n    }\n\n    let newDay\n\n    for(let i = 1; date.getDay() != 0; i++) {\n        newDay = initialDay - i\n        date.setDate(newDay)\n        console.log(date)\n    }\n    \n    for (let i = 0; i \u003c 7; i++) {\n\n        date.setDate(newDay + i)\n\n        let day = await prisma.day.create({\n            data: {\n                date: date,\n                name: daysNames[date.getDay()],\n                Week: {\n                    connect: {\n                        id: week.id,\n                    }\n                },\n            },\n            include: {\n                tarefas: true,\n            }\n        })\n        days.push(day)\n\n    }\n\n    week[\"days\"] = days\n    console.log(week)\n\n    return week\n}\n```\nMas antes é necessário ver se o dia de hoje já não está atribuido a uma semana.\nEntão dentro da rota '/week' (Método GET) executo essa verificação. \n```js\nweekRouter.get('/week', async (req, res) =\u003e {\n    ...\n    let today = new Date() \n    if (weeks[0].days[6].date.getTime() \u003c today.getTime()) {\n        let week = await createWeek()\n        weeks.unshift(week)\n    }\n    ...\n})\n```\n\n#### Tabela task\n#### Necessidade Constante da verificação de horas\n\n#### Funções para ajustar contagem de horas\n-Somar Horas\n```js\nasync function sumHours(task){\n    let day = await prisma.day.findFirst({\n        where: {\n            id: task.day\n        }\n    })\n\n    await prisma.day.update({\n        where: {\n            id: day.id\n        },\n        data: {\n            hours: day.hours + task.hours\n        }\n    })\n\n    let week = await prisma.week.findFirst({\n        where: {\n            id: day.week\n        }\n    })\n\n    await prisma.week.update({\n        where: {\n            id: week.id\n        },\n        data: {\n            hours: week.hours + task.hours\n        }\n    })\n}\n```\n\n-Subtrair Horas\n```js\nasync function subHours(task){\n    let day = await prisma.day.findFirst({\n        where: {\n            id: task.day\n        }\n    })\n\n    await prisma.day.update({\n        where: {\n            id: day.id\n        },\n        data: {\n            hours: day.hours - task.hours\n        }\n    })\n\n    let week = await prisma.week.findFirst({\n        where: {\n            id: day.week\n        }\n    })\n\n    await prisma.week.update({\n        where: {\n            id: week.id\n        },\n        data: {\n            hours: week.hours - task.hours\n        }\n    })\n}    \n```\n\nEm caso de qualquer alteração em alguma tarefa se fez muito necessária a verificação das horas. Para não haver erros na contagem de horas tanto dos Dias ou da Semana, é necessário verificar se a tarefa está como \"completa\", em cada caso:\n\n#### Rota '/task/completed '\nSe a requisição for para completar a tarefa:  \n- Adicionar as horas para o Dia e Semana respectivos;\n\nSe a requisição for para desmarcar a tarefa como completa:  \n- Remover as horas do Dia e Semana respectivos;\n\n```js\n// Se inicialmente a tarefa não fosse completa, mas agora fosse completa =\u003e Somar horas na semana e no dia;\n\ntaskRouter.post('/task/completed', async (req, res) =\u003e {\n\n    const { id, completed } = req.body\n\n    ...\n\n    if (!initialTask.completed \u0026\u0026 !!completed) {\n\n            await sumHours(initialTask)\n\n    } else if (initialTask.completed \u0026\u0026 !completed) {\n            \n            // Se inicialmente a tarefa fosse completa, mas agora não fosse completa =\u003e Subtrair horas na semana e no dia;\n            await subHours(initialTask)\n\n    }\n\n    ...\n\n}\n```\n\n#### Rota '/task/update '\nPara evitar erros, ao início da rota e possíveis erros com na contagem de horas:\n\n- Se a tarefa estiver marcada como \"completa\", seriam removidas as horas da tarefa inicialmente.\n\n- Se a tarefa não estiver marcada como \"completa\", não há necessidades de alterações.\n\n```js \ntaskRouter.post('/task/update', async (req, res) =\u003e {\n    \n    // Declaração da tarefa inicial\n    let initialTask = await prisma.task.findFirst({\n        where: {\n            id,\n        },\n    })\n\n    // Se for completa, desconto das horas\n    if (initialTask.completed) {\n\n        await subHours(initialTask)\n\n    }\n\n    ...\n\n    // Após todas as operações necessárias, é efetuada o update da \"task\"\n    let task = await prisma.task.update({\n        where: {\n            id,\n        },\n        data: {...},\n        include: {...}\n    })\n\n    // Se a tarefa estiver completa eu refaço o cálculo de horas que descontei lá no começo\n    if (task.completed) {\n\n        await sumHours(task)\n\n    }\n\n    ...\n\n})\n```\n\n#### Rota '/task/delete'\nPara não haver erro na contagem de horas, caso a tarefa esteja marcada como completa, é necessário descontar as horas dele tanto do dia tanto da semana, para enfim poder apagar.\n```js\ntaskRouter.post('/task/delete', async (req, res) =\u003e {\n    const { id } = req.body\n\n    ...\n\n    // Declaração da tarefa e exclusão\n    let task = await prisma.task.delete({\n        where: {\n            id,\n        },\n    })\n\n    // Se a tarefa estava \"completa\", é necessário subtrair as horas dela\n    if (task.completed) {\n\n        await subHours(task)\n\n    }\n\n    ...\n\n})\n```\n\n## Uso\nO uso de * representa a não obrigatóriedade.\n\n### Week\n\n#### /week (SELECT)\n\n- ID* - É possivel passar um id como filtro do Where, exemplo: /week/?id=1 (Valor Int);\n\n#### /week/create (CREATE)\n\n- Não são necessários parâmetros, é criado automáticamente.\n\n#### /week/delete (DELETE)\n\n- ID - É necessário passar um id para excluir a semana, formato Int, exemplo:\n```json\n{\n    \"id\": 1\n}\n``` \n\n### Task\n\n#### /task (SELECT)\n\n- ID* - É possivel passar um id como filtro do Where, exemplo: /task/?id=1 (Valor Int);\n- Day* - É possivel passar um day (id do Day) como filtro do Where, exemplo: /task/?day=1 (Valor Int);\n- Title* - É possível passar um title (título da tarefa) para filtrar no Where, exemplo: /task/?title=Titulo.\n\n#### /task/create (CREATE)\n\n- Title - Título da tarefa, formato String;\n- Desc - Descrição da tarefa, mais detalhado que o título, formato String;\n- Primeira_hora - Hora do começo do tarefa, formato String, mais especifícamente no seguinte formato: '00:00';\n- Ultima_hora - Hora do fim da tarefa, formato String, mais especifícamente no seguinte formato: '00:00';\n- Day - id do Day respectivo a tarefa, formato Int;\n- Categorie - id da Categorie respectiva a tarefa, formato Int.\n\nExemplo:\n```json\n{\n\t\"title\": \"Exemplo\",\n\t\"desc\": \"Este é apenas um exemplo de descrição.\",\n\t\"primeira_hora\": \"08:00\",\n\t\"ultima_hora\": \"10:00\",\n\t\"day\": 1,\n\t\"categorie\": 1\n}\n```\n\n#### /task/update (UPDATE)\n\n- ID - É necessário passar um id para atualizar a semana, formato Int;\n- Title* - Título da tarefa, formato String;\n- Desc* - Descrição da tarefa, mais detalhado que o título, formato String;\n- Primeira_hora* - Hora do começo do tarefa, formato String, mais especifícamente no seguinte formato: '00:00';\n- Ultima_hora* - Hora do fim da tarefa, formato String, mais especifícamente no seguinte formato: '00:00';\n- Day* - id do Day respectivo a tarefa, formato Int;\n- Categorie* - id da Categorie respectiva a tarefa, formato Int.\n\nExemplo:\n\nVale lembrar, pode ser enviado sem todos os valores, o único 100% obrigatório é o id.\n```json\n{\n    \"id\": 1, \n\t\"title\": \"Exemplo\",\n\t\"desc\": \"Este é apenas um exemplo de descrição.\",\n\t\"primeira_hora\": \"08:00\",\n\t\"ultima_hora\": \"10:00\",\n\t\"day\": 1,\n\t\"categorie\": 1\n}\n```\n\n#### /task/completed (UPDATE)\n\n- ID - É necessário passar um id para atualizar a semana, formato Int;\n- Completed* - Status da tarefa (completa ou não), formato Booleano;\n\nExemplo:\n```json\n{\n    \"id\": 1, \n\t\"completed\": true \n}\n```\n\n#### /task/delete (DELETE)\n\n- ID - É necessário passar um id para excluir a tarefa, formato Int, exemplo:\n```json\n{\n    \"id\": 1\n}\n``` \n\n### Categorie\n\n#### /categorie (SELECT)\n\n- ID* - É possivel passar um id como filtro do Where, exemplo: /categorie/?id=1 (tipo String);\n- Title* - É possivel passar um title como filtro do Where, exemplo: /categorie/?title=Titulo (tipo String);\n\n#### /categorie/create (CREATE)\n\n- Title - É necessário passar um title(Titulo) para a criação de uma categoria (tipo String).\n- Color - É necessário passar uma color(Cor) para a criação de uma categoria (tipo String).\n\nExemplo:\n```json\n{\n    \"title\": \"Titulo\",\n    \"color\": \"#00ff00\"\n}\n```\n\n#### /categorie/update (UPDATE)\n\n- ID - É necessário passar um id para atualizar a categoria (tipo Int);\n- Title* - É possível passar um title(Titulo) para atualizar uma categoria (tipo String).\n- Color* - É possível passar uma color(Cor) para atualizar uma categoria (tipo String).\n\nExemplo:\n```json\n{\n    \"id\": 1, \n    \"title\": \"Titulo\",\n    \"color\": \"#00ff00\"\n}\n```\n\n#### /categorie/delete (DELETE)\n\n- ID - É necessário passar um id para excluir a categoria(formato Int), exemplo:\n```json\n{\n    \"id\": 1\n}\n``` \n\n### Prompt\n\n#### /prompt (SELECT)\n\n- Question* - É possivel passar uma pergunta como filtro do Where, exemplo: /prompt/?question=Pergunta (tipo String);\n- Response* - É possivel passar uma resposta como filtro do Where, exemplo: /prompt/?prompt=Resposta (tipo String);\n\n#### /prompt/create (CREATE)\n\n- Question - É necessário passar uma question(pergunta) para a criação de um prompt (tipo String).\n\nExemplo:\n```json\n{\n    \"question\": \"Que dia é hoje?\"\n}\n```\n\n#### /prompt/update (UPDATE)\n\n- ID - É necessário passar um id para atualizar o prompt(tipo Int);\n- Question - É necessário passar uma question(pergunta) para atualização de um prompt (tipo String).\n\nExemplo:\n```json\n{\n    \"id\": 1, \n    \"question\": \"Que dia será amanhã?\"\n}\n```\n\n#### /prompt/delete (DELETE)\n\n- ID - É necessário passar um id para excluir o prompt(formato Int), exemplo:\n```json\n{\n    \"id\": 1\n}\n```\n\n## Restante do projeto\n[Study+ FrontEnd](https://github.com/Victor-Lis/StudyPlus-Front-End)\n\n## Instalação do Projeto\n```cmd\ngit clone https://github.com/Victor-Lis/StudyPlus-Front-End \u0026 git clone https://github.com/Victor-Lis/StudyPlus-Back-End\n```\n\n## Inicialização \nNo endereço do repositório do Front-End\n```cmd\nnpm start\n```\n\nNo endereço do repositório do Back-End\n```cmd\nnpm run dev\n```\n\n## Autores\n\n- [@Victor-Lis](https://github.com/Victor-Lis)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictor-lis%2Fstudyplus-back-end","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvictor-lis%2Fstudyplus-back-end","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictor-lis%2Fstudyplus-back-end/lists"}