From c41c4891a5ff86c38d31360a77b22c45d1b5ab39 Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Wed, 12 Nov 2025 16:22:18 -0300 Subject: [PATCH 01/42] App creation --- .dockerignore | 51 +++ .gitattributes | 9 + .github/dependabot.yml | 12 + .github/workflows/ci.yml | 90 ++++ .gitignore | 34 ++ .kamal/hooks/docker-setup.sample | 3 + .kamal/hooks/post-app-boot.sample | 3 + .kamal/hooks/post-deploy.sample | 14 + .kamal/hooks/post-proxy-reboot.sample | 3 + .kamal/hooks/pre-app-boot.sample | 3 + .kamal/hooks/pre-build.sample | 51 +++ .kamal/hooks/pre-connect.sample | 47 ++ .kamal/hooks/pre-deploy.sample | 122 ++++++ .kamal/hooks/pre-proxy-reboot.sample | 3 + .kamal/secrets | 17 + .rubocop.yml | 8 + .ruby-version | 1 + Dockerfile | 72 ++++ Gemfile | 63 +++ Gemfile.lock | 400 ++++++++++++++++++ README.md | 26 +- Rakefile | 6 + app/assets/images/.keep | 0 app/assets/stylesheets/application.css | 10 + app/controllers/application_controller.rb | 4 + app/controllers/concerns/.keep | 0 app/helpers/application_helper.rb | 2 + app/javascript/application.js | 3 + app/javascript/controllers/application.js | 9 + .../controllers/hello_controller.js | 7 + app/javascript/controllers/index.js | 4 + app/jobs/application_job.rb | 7 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/views/layouts/application.html.erb | 28 ++ app/views/layouts/mailer.html.erb | 13 + app/views/layouts/mailer.text.erb | 1 + app/views/pwa/manifest.json.erb | 22 + app/views/pwa/service-worker.js | 26 ++ bin/brakeman | 7 + bin/dev | 2 + bin/docker-entrypoint | 14 + bin/importmap | 4 + bin/jobs | 6 + bin/kamal | 16 + bin/rails | 4 + bin/rake | 4 + bin/rubocop | 8 + bin/setup | 34 ++ bin/thrust | 5 + config.ru | 6 + config/application.rb | 27 ++ config/boot.rb | 4 + config/cable.yml | 17 + config/cache.yml | 16 + config/credentials.yml.enc | 1 + config/database.yml | 41 ++ config/deploy.yml | 116 +++++ config/environment.rb | 5 + config/environments/development.rb | 72 ++++ config/environments/production.rb | 90 ++++ config/environments/test.rb | 53 +++ config/importmap.rb | 7 + config/initializers/assets.rb | 7 + .../initializers/content_security_policy.rb | 25 ++ .../initializers/filter_parameter_logging.rb | 8 + config/initializers/inflections.rb | 16 + config/locales/en.yml | 31 ++ config/puma.rb | 41 ++ config/queue.yml | 18 + config/recurring.yml | 15 + config/routes.rb | 14 + config/storage.yml | 34 ++ db/cable_schema.rb | 11 + db/cache_schema.rb | 12 + db/queue_schema.rb | 129 ++++++ db/seeds.rb | 9 + lib/tasks/.keep | 0 log/.keep | 0 public/400.html | 114 +++++ public/404.html | 114 +++++ public/406-unsupported-browser.html | 114 +++++ public/422.html | 114 +++++ public/500.html | 114 +++++ public/icon.png | Bin 0 -> 4166 bytes public/icon.svg | 3 + public/robots.txt | 1 + script/.keep | 0 storage/.keep | 0 test/application_system_test_case.rb | 5 + test/controllers/.keep | 0 test/fixtures/files/.keep | 0 test/helpers/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/system/.keep | 0 test/test_helper.rb | 15 + tmp/.keep | 0 tmp/pids/.keep | 0 tmp/storage/.keep | 0 vendor/.keep | 0 vendor/javascript/.keep | 0 104 files changed, 2702 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100755 .kamal/hooks/docker-setup.sample create mode 100755 .kamal/hooks/post-app-boot.sample create mode 100755 .kamal/hooks/post-deploy.sample create mode 100755 .kamal/hooks/post-proxy-reboot.sample create mode 100755 .kamal/hooks/pre-app-boot.sample create mode 100755 .kamal/hooks/pre-build.sample create mode 100755 .kamal/hooks/pre-connect.sample create mode 100755 .kamal/hooks/pre-deploy.sample create mode 100755 .kamal/hooks/pre-proxy-reboot.sample create mode 100644 .kamal/secrets create mode 100644 .rubocop.yml create mode 100644 .ruby-version create mode 100644 Dockerfile create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Rakefile create mode 100644 app/assets/images/.keep create mode 100644 app/assets/stylesheets/application.css create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/helpers/application_helper.rb create mode 100644 app/javascript/application.js create mode 100644 app/javascript/controllers/application.js create mode 100644 app/javascript/controllers/hello_controller.js create mode 100644 app/javascript/controllers/index.js create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/application.html.erb create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100644 app/views/pwa/manifest.json.erb create mode 100644 app/views/pwa/service-worker.js create mode 100755 bin/brakeman create mode 100755 bin/dev create mode 100755 bin/docker-entrypoint create mode 100755 bin/importmap create mode 100755 bin/jobs create mode 100755 bin/kamal create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/rubocop create mode 100755 bin/setup create mode 100755 bin/thrust create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/cache.yml create mode 100644 config/credentials.yml.enc create mode 100644 config/database.yml create mode 100644 config/deploy.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/importmap.rb create mode 100644 config/initializers/assets.rb create mode 100644 config/initializers/content_security_policy.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/queue.yml create mode 100644 config/recurring.yml create mode 100644 config/routes.rb create mode 100644 config/storage.yml create mode 100644 db/cable_schema.rb create mode 100644 db/cache_schema.rb create mode 100644 db/queue_schema.rb create mode 100644 db/seeds.rb create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/400.html create mode 100644 public/404.html create mode 100644 public/406-unsupported-browser.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/icon.png create mode 100644 public/icon.svg create mode 100644 public/robots.txt create mode 100644 script/.keep create mode 100644 storage/.keep create mode 100644 test/application_system_test_case.rb create mode 100644 test/controllers/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/helpers/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/system/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 tmp/pids/.keep create mode 100644 tmp/storage/.keep create mode 100644 vendor/.keep create mode 100644 vendor/javascript/.keep diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..325bfc036d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,51 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ +/.gitignore + +# Ignore bundler config. +/.bundle + +# Ignore all environment files. +/.env* + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets + +# Ignore CI service files. +/.github + +# Ignore Kamal files. +/config/deploy*.yml +/.kamal + +# Ignore development files +/.devcontainer + +# Ignore Docker-related files +/.dockerignore +/Dockerfile* diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..8dc4323435 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored +config/credentials/*.yml.enc diff=rails_credentials +config/credentials.yml.enc diff=rails_credentials diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..f0527e6be1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: +- package-ecosystem: bundler + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..7b7c0c59b3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,90 @@ +name: CI + +on: + pull_request: + push: + branches: [ main ] + +jobs: + scan_ruby: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Scan for common Rails security vulnerabilities using static analysis + run: bin/brakeman --no-pager + + scan_js: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Scan for security vulnerabilities in JavaScript dependencies + run: bin/importmap audit + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Lint code for consistent style + run: bin/rubocop -f github + + test: + runs-on: ubuntu-latest + + # services: + # redis: + # image: redis + # ports: + # - 6379:6379 + # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 + steps: + - name: Install packages + run: sudo apt-get update && sudo apt-get install --no-install-recommends -y build-essential git libyaml-dev pkg-config google-chrome-stable + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run tests + env: + RAILS_ENV: test + # REDIS_URL: redis://localhost:6379/0 + run: bin/rails db:test:prepare test test:system + + - name: Keep screenshots from failed system tests + uses: actions/upload-artifact@v4 + if: failure() + with: + name: screenshots + path: ${{ github.workspace }}/tmp/screenshots + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..f92525ca5e --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# Temporary files generated by your text editor or operating system +# belong in git's global ignore instead: +# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` + +# Ignore bundler config. +/.bundle + +# Ignore all environment files. +/.env* + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/ +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + +/public/assets + +# Ignore master key for decrypting credentials and more. +/config/master.key diff --git a/.kamal/hooks/docker-setup.sample b/.kamal/hooks/docker-setup.sample new file mode 100755 index 0000000000..2fb07d7d7a --- /dev/null +++ b/.kamal/hooks/docker-setup.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Docker set up on $KAMAL_HOSTS..." diff --git a/.kamal/hooks/post-app-boot.sample b/.kamal/hooks/post-app-boot.sample new file mode 100755 index 0000000000..70f9c4bc95 --- /dev/null +++ b/.kamal/hooks/post-app-boot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Booted app version $KAMAL_VERSION on $KAMAL_HOSTS..." diff --git a/.kamal/hooks/post-deploy.sample b/.kamal/hooks/post-deploy.sample new file mode 100755 index 0000000000..fd364c2a77 --- /dev/null +++ b/.kamal/hooks/post-deploy.sample @@ -0,0 +1,14 @@ +#!/bin/sh + +# A sample post-deploy hook +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" diff --git a/.kamal/hooks/post-proxy-reboot.sample b/.kamal/hooks/post-proxy-reboot.sample new file mode 100755 index 0000000000..1435a677f2 --- /dev/null +++ b/.kamal/hooks/post-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooted kamal-proxy on $KAMAL_HOSTS" diff --git a/.kamal/hooks/pre-app-boot.sample b/.kamal/hooks/pre-app-boot.sample new file mode 100755 index 0000000000..45f7355045 --- /dev/null +++ b/.kamal/hooks/pre-app-boot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Booting app version $KAMAL_VERSION on $KAMAL_HOSTS..." diff --git a/.kamal/hooks/pre-build.sample b/.kamal/hooks/pre-build.sample new file mode 100755 index 0000000000..c5a55678b2 --- /dev/null +++ b/.kamal/hooks/pre-build.sample @@ -0,0 +1,51 @@ +#!/bin/sh + +# A sample pre-build hook +# +# Checks: +# 1. We have a clean checkout +# 2. A remote is configured +# 3. The branch has been pushed to the remote +# 4. The version we are deploying matches the remote +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) + +if [ -n "$(git status --porcelain)" ]; then + echo "Git checkout is not clean, aborting..." >&2 + git status --porcelain >&2 + exit 1 +fi + +first_remote=$(git remote) + +if [ -z "$first_remote" ]; then + echo "No git remote set, aborting..." >&2 + exit 1 +fi + +current_branch=$(git branch --show-current) + +if [ -z "$current_branch" ]; then + echo "Not on a git branch, aborting..." >&2 + exit 1 +fi + +remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1) + +if [ -z "$remote_head" ]; then + echo "Branch not pushed to remote, aborting..." >&2 + exit 1 +fi + +if [ "$KAMAL_VERSION" != "$remote_head" ]; then + echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2 + exit 1 +fi + +exit 0 diff --git a/.kamal/hooks/pre-connect.sample b/.kamal/hooks/pre-connect.sample new file mode 100755 index 0000000000..77744bdca8 --- /dev/null +++ b/.kamal/hooks/pre-connect.sample @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +# A sample pre-connect check +# +# Warms DNS before connecting to hosts in parallel +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +hosts = ENV["KAMAL_HOSTS"].split(",") +results = nil +max = 3 + +elapsed = Benchmark.realtime do + results = hosts.map do |host| + Thread.new do + tries = 1 + + begin + Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) + rescue SocketError + if tries < max + puts "Retrying DNS warmup: #{host}" + tries += 1 + sleep rand + retry + else + puts "DNS warmup failed: #{host}" + host + end + end + + tries + end + end.map(&:value) +end + +retries = results.sum - hosts.size +nopes = results.count { |r| r == max } + +puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ] diff --git a/.kamal/hooks/pre-deploy.sample b/.kamal/hooks/pre-deploy.sample new file mode 100755 index 0000000000..05b3055b72 --- /dev/null +++ b/.kamal/hooks/pre-deploy.sample @@ -0,0 +1,122 @@ +#!/usr/bin/env ruby + +# A sample pre-deploy hook +# +# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds. +# +# Fails unless the combined status is "success" +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_COMMAND +# KAMAL_SUBCOMMAND +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) + +# Only check the build status for production deployments +if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production" + exit 0 +end + +require "bundler/inline" + +# true = install gems so this is fast on repeat invocations +gemfile(true, quiet: true) do + source "https://rubygems.org" + + gem "octokit" + gem "faraday-retry" +end + +MAX_ATTEMPTS = 72 +ATTEMPTS_GAP = 10 + +def exit_with_error(message) + $stderr.puts message + exit 1 +end + +class GithubStatusChecks + attr_reader :remote_url, :git_sha, :github_client, :combined_status + + def initialize + @remote_url = github_repo_from_remote_url + @git_sha = `git rev-parse HEAD`.strip + @github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) + refresh! + end + + def refresh! + @combined_status = github_client.combined_status(remote_url, git_sha) + end + + def state + combined_status[:state] + end + + def first_status_url + first_status = combined_status[:statuses].find { |status| status[:state] == state } + first_status && first_status[:target_url] + end + + def complete_count + combined_status[:statuses].count { |status| status[:state] != "pending"} + end + + def total_count + combined_status[:statuses].count + end + + def current_status + if total_count > 0 + "Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..." + else + "Build not started..." + end + end + + private + def github_repo_from_remote_url + url = `git config --get remote.origin.url`.strip.delete_suffix(".git") + if url.start_with?("https://github.com/") + url.delete_prefix("https://github.com/") + elsif url.start_with?("git@github.com:") + url.delete_prefix("git@github.com:") + else + url + end + end +end + + +$stdout.sync = true + +begin + puts "Checking build status..." + + attempts = 0 + checks = GithubStatusChecks.new + + loop do + case checks.state + when "success" + puts "Checks passed, see #{checks.first_status_url}" + exit 0 + when "failure" + exit_with_error "Checks failed, see #{checks.first_status_url}" + when "pending" + attempts += 1 + end + + exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS + + puts checks.current_status + sleep(ATTEMPTS_GAP) + checks.refresh! + end +rescue Octokit::NotFound + exit_with_error "Build status could not be found" +end diff --git a/.kamal/hooks/pre-proxy-reboot.sample b/.kamal/hooks/pre-proxy-reboot.sample new file mode 100755 index 0000000000..061f8059e6 --- /dev/null +++ b/.kamal/hooks/pre-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." diff --git a/.kamal/secrets b/.kamal/secrets new file mode 100644 index 0000000000..9a771a3985 --- /dev/null +++ b/.kamal/secrets @@ -0,0 +1,17 @@ +# Secrets defined here are available for reference under registry/password, env/secret, builder/secrets, +# and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either +# password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git. + +# Example of extracting secrets from 1password (or another compatible pw manager) +# SECRETS=$(kamal secrets fetch --adapter 1password --account your-account --from Vault/Item KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY) +# KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS}) +# RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY ${SECRETS}) + +# Use a GITHUB_TOKEN if private repositories are needed for the image +# GITHUB_TOKEN=$(gh config get -h github.com oauth_token) + +# Grab the registry password from ENV +KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD + +# Improve security by using a password manager. Never check config/master.key into git! +RAILS_MASTER_KEY=$(cat config/master.key) diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000000..f9d86d4a54 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,8 @@ +# Omakase Ruby styling for Rails +inherit_gem: { rubocop-rails-omakase: rubocop.yml } + +# Overwrite or add rules to create your own house style +# +# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` +# Layout/SpaceInsideArrayLiteralBrackets: +# Enabled: false diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000000..3b47f2e4f8 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.3.9 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..4ba3d017fd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,72 @@ +# syntax=docker/dockerfile:1 +# check=error=true + +# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: +# docker build -t camaar_g1 . +# docker run -d -p 80:80 -e RAILS_MASTER_KEY= --name camaar_g1 camaar_g1 + +# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.3.9 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base + +# Rails app lives here +WORKDIR /rails + +# Install base packages +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" + +# Throw-away build stage to reduce size of final image +FROM base AS build + +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git libyaml-dev pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile + +# Copy application code +COPY . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ + +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + + + +# Final stage for app image +FROM base + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER 1000:1000 + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start server via Thruster by default, this can be overwritten at runtime +EXPOSE 80 +CMD ["./bin/thrust", "./bin/rails", "server"] diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000..ed45b5b828 --- /dev/null +++ b/Gemfile @@ -0,0 +1,63 @@ +source "https://rubygems.org" + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 8.0.2", ">= 8.0.2.1" +# The modern asset pipeline for Rails [https://github.com/rails/propshaft] +gem "propshaft" +# Use sqlite3 as the database for Active Record +gem "sqlite3", ">= 2.1" +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Use the database-backed adapters for Rails.cache, Active Job, and Action Cable +gem "solid_cache" +gem "solid_queue" +gem "solid_cable" + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Deploy this application anywhere as a Docker container [https://kamal-deploy.org] +gem "kamal", require: false + +# Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/] +gem "thruster", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + + # Static analysis for security vulnerabilities [https://brakemanscanner.org/] + gem "brakeman", require: false + + # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] + gem "rubocop-rails-omakase", require: false +end + +group :development do + # Use console on exceptions pages [https://github.com/rails/web-console] + gem "web-console" +end + +group :test do + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + gem "capybara" + gem "selenium-webdriver" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000..75d2d41720 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,400 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (8.0.4) + actionpack (= 8.0.4) + activesupport (= 8.0.4) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (8.0.4) + actionpack (= 8.0.4) + activejob (= 8.0.4) + activerecord (= 8.0.4) + activestorage (= 8.0.4) + activesupport (= 8.0.4) + mail (>= 2.8.0) + actionmailer (8.0.4) + actionpack (= 8.0.4) + actionview (= 8.0.4) + activejob (= 8.0.4) + activesupport (= 8.0.4) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.0.4) + actionview (= 8.0.4) + activesupport (= 8.0.4) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.0.4) + actionpack (= 8.0.4) + activerecord (= 8.0.4) + activestorage (= 8.0.4) + activesupport (= 8.0.4) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (8.0.4) + activesupport (= 8.0.4) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (8.0.4) + activesupport (= 8.0.4) + globalid (>= 0.3.6) + activemodel (8.0.4) + activesupport (= 8.0.4) + activerecord (8.0.4) + activemodel (= 8.0.4) + activesupport (= 8.0.4) + timeout (>= 0.4.0) + activestorage (8.0.4) + actionpack (= 8.0.4) + activejob (= 8.0.4) + activerecord (= 8.0.4) + activesupport (= 8.0.4) + marcel (~> 1.0) + activesupport (8.0.4) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + ast (2.4.3) + base64 (0.3.0) + bcrypt_pbkdf (1.1.1) + bcrypt_pbkdf (1.1.1-arm64-darwin) + bcrypt_pbkdf (1.1.1-x86_64-darwin) + benchmark (0.5.0) + bigdecimal (3.3.1) + bindex (0.8.1) + bootsnap (1.18.6) + msgpack (~> 1.2) + brakeman (7.1.1) + racc + builder (3.3.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + crass (1.0.6) + date (3.5.0) + debug (1.11.0) + irb (~> 1.10) + reline (>= 0.3.8) + dotenv (3.1.8) + drb (2.2.3) + ed25519 (1.4.0) + erb (5.1.3) + erubi (1.13.1) + et-orbi (1.4.0) + tzinfo + fugit (1.12.1) + et-orbi (~> 1.4) + raabro (~> 1.4) + globalid (1.3.0) + activesupport (>= 6.1) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + importmap-rails (2.2.2) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.8.1) + irb (1.15.3) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.14.1) + actionview (>= 7.0.0) + activesupport (>= 7.0.0) + json (2.16.0) + kamal (2.8.2) + activesupport (>= 7.0) + base64 (~> 0.2) + bcrypt_pbkdf (~> 1.0) + concurrent-ruby (~> 1.2) + dotenv (~> 3.1) + ed25519 (~> 1.4) + net-ssh (~> 7.3) + sshkit (>= 1.23.0, < 2.0) + thor (~> 1.3) + zeitwerk (>= 2.6.18, < 3.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.1.0) + matrix (0.4.3) + mini_mime (1.1.5) + minitest (5.26.1) + msgpack (1.8.0) + net-imap (0.5.12) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-scp (4.1.0) + net-ssh (>= 2.6.5, < 8.0.0) + net-sftp (4.0.0) + net-ssh (>= 5.0.0, < 8.0.0) + net-smtp (0.5.1) + net-protocol + net-ssh (7.3.0) + nio4r (2.7.5) + nokogiri (1.18.10-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-musl) + racc (~> 1.4) + ostruct (0.6.3) + parallel (1.27.0) + parser (3.3.10.0) + ast (~> 2.4.1) + racc + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.6.0) + propshaft (1.3.1) + actionpack (>= 7.0.0) + activesupport (>= 7.0.0) + rack + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + puma (7.1.0) + nio4r (~> 2.0) + raabro (1.4.0) + racc (1.8.1) + rack (3.2.4) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (8.0.4) + actioncable (= 8.0.4) + actionmailbox (= 8.0.4) + actionmailer (= 8.0.4) + actionpack (= 8.0.4) + actiontext (= 8.0.4) + actionview (= 8.0.4) + activejob (= 8.0.4) + activemodel (= 8.0.4) + activerecord (= 8.0.4) + activestorage (= 8.0.4) + activesupport (= 8.0.4) + bundler (>= 1.15.0) + railties (= 8.0.4) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.0.4) + actionpack (= 8.0.4) + activesupport (= 8.0.4) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.1) + rdoc (6.15.1) + erb + psych (>= 4.0.0) + tsort + regexp_parser (2.11.3) + reline (0.6.3) + io-console (~> 0.5) + rexml (3.4.4) + rubocop (1.81.7) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.48.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.26.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) + rubocop-rails (2.33.4) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rails-omakase (1.1.0) + rubocop (>= 1.72) + rubocop-performance (>= 1.24) + rubocop-rails (>= 2.30) + ruby-progressbar (1.13.0) + rubyzip (3.2.2) + securerandom (0.4.1) + selenium-webdriver (4.38.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 4.0) + websocket (~> 1.0) + solid_cable (3.0.12) + actioncable (>= 7.2) + activejob (>= 7.2) + activerecord (>= 7.2) + railties (>= 7.2) + solid_cache (1.0.10) + activejob (>= 7.2) + activerecord (>= 7.2) + railties (>= 7.2) + solid_queue (1.2.4) + activejob (>= 7.1) + activerecord (>= 7.1) + concurrent-ruby (>= 1.3.1) + fugit (~> 1.11) + railties (>= 7.1) + thor (>= 1.3.1) + sqlite3 (2.8.0-aarch64-linux-gnu) + sqlite3 (2.8.0-aarch64-linux-musl) + sqlite3 (2.8.0-arm-linux-gnu) + sqlite3 (2.8.0-arm-linux-musl) + sqlite3 (2.8.0-arm64-darwin) + sqlite3 (2.8.0-x86_64-darwin) + sqlite3 (2.8.0-x86_64-linux-gnu) + sqlite3 (2.8.0-x86_64-linux-musl) + sshkit (1.24.0) + base64 + logger + net-scp (>= 1.1.2) + net-sftp (>= 2.1.2) + net-ssh (>= 2.8.0) + ostruct + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringio (3.1.8) + thor (1.4.0) + thruster (0.1.16) + thruster (0.1.16-aarch64-linux) + thruster (0.1.16-arm64-darwin) + thruster (0.1.16-x86_64-darwin) + thruster (0.1.16-x86_64-linux) + timeout (0.4.4) + tsort (0.2.0) + turbo-rails (2.0.20) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + uri (1.1.1) + useragent (0.16.11) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + bootsnap + brakeman + capybara + debug + importmap-rails + jbuilder + kamal + propshaft + puma (>= 5.0) + rails (~> 8.0.2, >= 8.0.2.1) + rubocop-rails-omakase + selenium-webdriver + solid_cable + solid_cache + solid_queue + sqlite3 (>= 2.1) + stimulus-rails + thruster + turbo-rails + tzinfo-data + web-console + +BUNDLED WITH + 2.7.1 diff --git a/README.md b/README.md index 9d7fe1bf53..7db80e4ca1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,24 @@ -# CAMAAR -Sistema para avaliação de atividades acadêmicas remotas do CIC +# README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000000..9a5ea7383a --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css new file mode 100644 index 0000000000..fe93333c0f --- /dev/null +++ b/app/assets/stylesheets/application.css @@ -0,0 +1,10 @@ +/* + * This is a manifest file that'll be compiled into application.css. + * + * With Propshaft, assets are served efficiently without preprocessing steps. You can still include + * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard + * cascading order, meaning styles declared later in the document or manifest will override earlier ones, + * depending on specificity. + * + * Consider organizing styles into separate files for maintainability. + */ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000000..0d95db22b4 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,4 @@ +class ApplicationController < ActionController::Base + # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. + allow_browser versions: :modern +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000000..de6be7945c --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/javascript/application.js b/app/javascript/application.js new file mode 100644 index 0000000000..0d7b49404c --- /dev/null +++ b/app/javascript/application.js @@ -0,0 +1,3 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "@hotwired/turbo-rails" +import "controllers" diff --git a/app/javascript/controllers/application.js b/app/javascript/controllers/application.js new file mode 100644 index 0000000000..1213e85c7a --- /dev/null +++ b/app/javascript/controllers/application.js @@ -0,0 +1,9 @@ +import { Application } from "@hotwired/stimulus" + +const application = Application.start() + +// Configure Stimulus development experience +application.debug = false +window.Stimulus = application + +export { application } diff --git a/app/javascript/controllers/hello_controller.js b/app/javascript/controllers/hello_controller.js new file mode 100644 index 0000000000..5975c0789d --- /dev/null +++ b/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js new file mode 100644 index 0000000000..1156bf8362 --- /dev/null +++ b/app/javascript/controllers/index.js @@ -0,0 +1,4 @@ +// Import and register all your controllers from the importmap via controllers/**/*_controller +import { application } from "controllers/application" +import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" +eagerLoadControllersFrom("controllers", application) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 0000000000..d394c3d106 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 0000000000..3c34c8148f --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000000..b63caeb8a5 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000000..1455450e14 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,28 @@ + + + + <%= content_for(:title) || "Camaar G1" %> + + + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= yield :head %> + + <%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %> + <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %> + + + + + + <%# Includes all stylesheet files in app/assets/stylesheets %> + <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000000..3aac9002ed --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000000..37f0bddbd7 --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/app/views/pwa/manifest.json.erb b/app/views/pwa/manifest.json.erb new file mode 100644 index 0000000000..d6cf3bbd6c --- /dev/null +++ b/app/views/pwa/manifest.json.erb @@ -0,0 +1,22 @@ +{ + "name": "CamaarG1", + "icons": [ + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512", + "purpose": "maskable" + } + ], + "start_url": "/", + "display": "standalone", + "scope": "/", + "description": "CamaarG1.", + "theme_color": "red", + "background_color": "red" +} diff --git a/app/views/pwa/service-worker.js b/app/views/pwa/service-worker.js new file mode 100644 index 0000000000..b3a13fb7bb --- /dev/null +++ b/app/views/pwa/service-worker.js @@ -0,0 +1,26 @@ +// Add a service worker for processing Web Push notifications: +// +// self.addEventListener("push", async (event) => { +// const { title, options } = await event.data.json() +// event.waitUntil(self.registration.showNotification(title, options)) +// }) +// +// self.addEventListener("notificationclick", function(event) { +// event.notification.close() +// event.waitUntil( +// clients.matchAll({ type: "window" }).then((clientList) => { +// for (let i = 0; i < clientList.length; i++) { +// let client = clientList[i] +// let clientPath = (new URL(client.url)).pathname +// +// if (clientPath == event.notification.data.path && "focus" in client) { +// return client.focus() +// } +// } +// +// if (clients.openWindow) { +// return clients.openWindow(event.notification.data.path) +// } +// }) +// ) +// }) diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 0000000000..ace1c9ba08 --- /dev/null +++ b/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") diff --git a/bin/dev b/bin/dev new file mode 100755 index 0000000000..5f91c20545 --- /dev/null +++ b/bin/dev @@ -0,0 +1,2 @@ +#!/usr/bin/env ruby +exec "./bin/rails", "server", *ARGV diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000000..57567d69b4 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,14 @@ +#!/bin/bash -e + +# Enable jemalloc for reduced memory usage and latency. +if [ -z "${LD_PRELOAD+x}" ]; then + LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) + export LD_PRELOAD +fi + +# If running the rails server then create or migrate existing database +if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/bin/importmap b/bin/importmap new file mode 100755 index 0000000000..36502ab16c --- /dev/null +++ b/bin/importmap @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +require_relative "../config/application" +require "importmap/commands" diff --git a/bin/jobs b/bin/jobs new file mode 100755 index 0000000000..dcf59f309a --- /dev/null +++ b/bin/jobs @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +require_relative "../config/environment" +require "solid_queue/cli" + +SolidQueue::Cli.start(ARGV) diff --git a/bin/kamal b/bin/kamal new file mode 100755 index 0000000000..d9ba276702 --- /dev/null +++ b/bin/kamal @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'kamal' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("kamal", "kamal") diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000000..efc0377492 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000000..4fbf10b960 --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "rake" +Rake.application.run diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000000..40330c0ff1 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000000..be3db3c0d6 --- /dev/null +++ b/bin/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require "fileutils" + +APP_ROOT = File.expand_path("..", __dir__) + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts "== Installing dependencies ==" + system("bundle check") || system!("bundle install") + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! "bin/rails db:prepare" + + puts "\n== Removing old logs and tempfiles ==" + system! "bin/rails log:clear tmp:clear" + + unless ARGV.include?("--skip-server") + puts "\n== Starting development server ==" + STDOUT.flush # flush the output before exec(2) so that it displays + exec "bin/dev" + end +end diff --git a/bin/thrust b/bin/thrust new file mode 100755 index 0000000000..36bde2d832 --- /dev/null +++ b/bin/thrust @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("thruster", "thrust") diff --git a/config.ru b/config.ru new file mode 100644 index 0000000000..4a3c09a688 --- /dev/null +++ b/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000000..72b52e0f11 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,27 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module CamaarG1 + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 8.0 + + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[assets tasks]) + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000000..988a5ddc46 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 0000000000..b9adc5aa3a --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,17 @@ +# Async adapter only works within the same process, so for manually triggering cable updates from a console, +# and seeing results in the browser, you must do so from the web console (running inside the dev process), +# not a terminal started via bin/rails console! Add "console" to any action or any ERB template view +# to make the web console appear. +development: + adapter: async + +test: + adapter: test + +production: + adapter: solid_cable + connects_to: + database: + writing: cable + polling_interval: 0.1.seconds + message_retention: 1.day diff --git a/config/cache.yml b/config/cache.yml new file mode 100644 index 0000000000..19d490843b --- /dev/null +++ b/config/cache.yml @@ -0,0 +1,16 @@ +default: &default + store_options: + # Cap age of oldest cache entry to fulfill retention policies + # max_age: <%= 60.days.to_i %> + max_size: <%= 256.megabytes %> + namespace: <%= Rails.env %> + +development: + <<: *default + +test: + <<: *default + +production: + database: cache + <<: *default diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc new file mode 100644 index 0000000000..5e95166c07 --- /dev/null +++ b/config/credentials.yml.enc @@ -0,0 +1 @@ +dG82hj0yB5jlVXL3V13vnZl7iIWRvVPx4qMlMg5yWkOEd6QuE6HpPOjWcx8acScjxkTLiSdpoUV3dGk+R8BTa+gyX8VkVuJM4UzcLUMQ4YlFd5craaf7jlqH4oUul0VEuFpH4387REN8JdaHIZdtal4r0+5bOAnnxzCDs2twIbSAyl13Nns0QS+/kAzj4Ge8oowivPsLtax/HloUO5Ovi+U/fUjgHZFdpfVbl0M4YA5y2HUUEEw/uRbvvi8KVM+ZE4Oa3OU0d+I5N0i4Suj+CBUOeHN//wACcP1QIbHo3y5h4NSLYJpFNkwg4MIOIcJXmJf/VJLoYsXKsohF03ioYBbbb5SCAJHX8mCHzjk5KMfbSYZMJDeOGGKZ+ZfT+dSB3dFjLKtoV9VNYTQ+Ll+Cbk4iBLn5X9M4vojcM+Q+MuPPTXEw6k2+oR8wlRt49Dez1Ar2cye9/eMRoiTsQu60GlSlDpbg9zeQ9vP/igmBOOGmv9ZIlJevO5P8--tkNmt0c6GGbUYEKp--YnPJEHyaQ1KPNB4TkhYHjA== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000000..2640cb5f30 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,41 @@ +# SQLite. Versions 3.8.0 and up are supported. +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem "sqlite3" +# +default: &default + adapter: sqlite3 + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +development: + <<: *default + database: storage/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: storage/test.sqlite3 + + +# Store production database in the storage/ directory, which by default +# is mounted as a persistent Docker volume in config/deploy.yml. +production: + primary: + <<: *default + database: storage/production.sqlite3 + cache: + <<: *default + database: storage/production_cache.sqlite3 + migrations_paths: db/cache_migrate + queue: + <<: *default + database: storage/production_queue.sqlite3 + migrations_paths: db/queue_migrate + cable: + <<: *default + database: storage/production_cable.sqlite3 + migrations_paths: db/cable_migrate diff --git a/config/deploy.yml b/config/deploy.yml new file mode 100644 index 0000000000..6188baa0b2 --- /dev/null +++ b/config/deploy.yml @@ -0,0 +1,116 @@ +# Name of your application. Used to uniquely configure containers. +service: camaar_g1 + +# Name of the container image. +image: your-user/camaar_g1 + +# Deploy to these servers. +servers: + web: + - 192.168.0.1 + # job: + # hosts: + # - 192.168.0.1 + # cmd: bin/jobs + +# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. +# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. +# +# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. +proxy: + ssl: true + host: app.example.com + +# Credentials for your image host. +registry: + # Specify the registry server, if you're not using Docker Hub + # server: registry.digitalocean.com / ghcr.io / ... + username: your-user + + # Always use an access token rather than real password when possible. + password: + - KAMAL_REGISTRY_PASSWORD + +# Inject ENV variables into containers (secrets come from .kamal/secrets). +env: + secret: + - RAILS_MASTER_KEY + clear: + # Run the Solid Queue Supervisor inside the web server's Puma process to do jobs. + # When you start using multiple servers, you should split out job processing to a dedicated machine. + SOLID_QUEUE_IN_PUMA: true + + # Set number of processes dedicated to Solid Queue (default: 1) + # JOB_CONCURRENCY: 3 + + # Set number of cores available to the application on each server (default: 1). + # WEB_CONCURRENCY: 2 + + # Match this to any external database server to configure Active Record correctly + # Use camaar_g1-db for a db accessory server on same machine via local kamal docker network. + # DB_HOST: 192.168.0.2 + + # Log everything from Rails + # RAILS_LOG_LEVEL: debug + +# Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation: +# "bin/kamal logs -r job" will tail logs from the first server in the job section. +aliases: + console: app exec --interactive --reuse "bin/rails console" + shell: app exec --interactive --reuse "bash" + logs: app logs -f + dbc: app exec --interactive --reuse "bin/rails dbconsole" + + +# Use a persistent storage volume for sqlite database files and local Active Storage files. +# Recommended to change this to a mounted volume path that is backed up off server. +volumes: + - "camaar_g1_storage:/rails/storage" + + +# Bridge fingerprinted assets, like JS and CSS, between versions to avoid +# hitting 404 on in-flight requests. Combines all files from new and old +# version inside the asset_path. +asset_path: /rails/public/assets + +# Configure the image builder. +builder: + arch: amd64 + + # # Build image via remote server (useful for faster amd64 builds on arm64 computers) + # remote: ssh://docker@docker-builder-server + # + # # Pass arguments and secrets to the Docker build process + # args: + # RUBY_VERSION: 3.3.9 + # secrets: + # - GITHUB_TOKEN + # - RAILS_MASTER_KEY + +# Use a different ssh user than root +# ssh: +# user: app + +# Use accessory services (secrets come from .kamal/secrets). +# accessories: +# db: +# image: mysql:8.0 +# host: 192.168.0.2 +# # Change to 3306 to expose port to the world instead of just local network. +# port: "127.0.0.1:3306:3306" +# env: +# clear: +# MYSQL_ROOT_HOST: '%' +# secret: +# - MYSQL_ROOT_PASSWORD +# files: +# - config/mysql/production.cnf:/etc/mysql/my.cnf +# - db/production.sql:/docker-entrypoint-initdb.d/setup.sql +# directories: +# - data:/var/lib/mysql +# redis: +# image: redis:7.0 +# host: 192.168.0.2 +# port: 6379 +# directories: +# - data:/data diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000000..cac5315775 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000000..4cc21c4ebe --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,72 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Make code changes take effect immediately without server restart. + config.enable_reloading = true + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing. + config.server_timing = true + + # Enable/disable Action Controller caching. By default Action Controller caching is disabled. + # Run rails dev:cache to toggle Action Controller caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } + else + config.action_controller.perform_caching = false + end + + # Change to :null_store to avoid any caching. + config.cache_store = :memory_store + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Make template changes take effect immediately. + config.action_mailer.perform_caching = false + + # Set localhost to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Append comments with runtime information tags to SQL queries in logs. + config.active_record.query_log_tags_enabled = true + + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true + + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000000..bdcd01d1bf --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,90 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.enable_reloading = false + + # Eager load code on boot for better performance and memory savings (ignored by Rake tasks). + config.eager_load = true + + # Full error reports are disabled. + config.consider_all_requests_local = false + + # Turn on fragment caching in view templates. + config.action_controller.perform_caching = true + + # Cache assets for far-future expiry since they are all digest stamped. + config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + config.assume_ssl = true + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = true + + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + + # Log to STDOUT with the current request id as a default log tag. + config.log_tags = [ :request_id ] + config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) + + # Change to "debug" to log everything (including potentially personally-identifiable information!) + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + + # Prevent health checks from clogging up the logs. + config.silence_healthcheck_path = "/up" + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Replace the default in-process memory cache store with a durable alternative. + config.cache_store = :solid_cache_store + + # Replace the default in-process and non-durable queuing backend for Active Job. + config.active_job.queue_adapter = :solid_queue + config.solid_queue.connects_to = { database: { writing: :queue } } + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } + + # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. + # config.action_mailer.smtp_settings = { + # user_name: Rails.application.credentials.dig(:smtp, :user_name), + # password: Rails.application.credentials.dig(:smtp, :password), + # address: "smtp.example.com", + # port: 587, + # authentication: :plain + # } + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Only use :id for inspections in production. + config.active_record.attributes_for_inspect = [ :id ] + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000000..c2095b1174 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,53 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with cache-control for performance. + config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } + + # Show full error reports. + config.consider_all_requests_local = true + config.cache_store = :null_store + + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/config/importmap.rb b/config/importmap.rb new file mode 100644 index 0000000000..909dfc542d --- /dev/null +++ b/config/importmap.rb @@ -0,0 +1,7 @@ +# Pin npm packages by running ./bin/importmap + +pin "application" +pin "@hotwired/turbo-rails", to: "turbo.min.js" +pin "@hotwired/stimulus", to: "stimulus.min.js" +pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" +pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000000..487324424f --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 0000000000..b3076b38fe --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src style-src) +# +# # Report violations without enforcing the policy. +# # config.content_security_policy_report_only = true +# end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000000..c0b717f7ec --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. +Rails.application.config.filter_parameters += [ + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc +] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000000..3860f659ea --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000000..6c349ae5e3 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,31 @@ +# Files in the config/locales directory are used for internationalization and +# are automatically loaded by Rails. If you want to use locales other than +# English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more about the API, please read the Rails Internationalization guide +# at https://guides.rubyonrails.org/i18n.html. +# +# Be aware that YAML interprets the following case-insensitive strings as +# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings +# must be quoted to be interpreted as strings. For example: +# +# en: +# "yes": yup +# enabled: "ON" + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 0000000000..a248513b24 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,41 @@ +# This configuration file will be evaluated by Puma. The top-level methods that +# are invoked here are part of Puma's configuration DSL. For more information +# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. +# +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. +# +# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You +# should only set this value when you want to run 2 or more workers. The +# default is already 1. +# +# The ideal number of threads per worker depends both on how much time the +# application spends waiting for IO operations and on how much you wish to +# prioritize throughput over latency. +# +# As a rule of thumb, increasing the number of threads will increase how much +# traffic a given process can handle (throughput), but due to CRuby's +# Global VM Lock (GVL) it has diminishing returns and will degrade the +# response time (latency) of the application. +# +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. +# +# Any libraries that use a connection pool or another resource pool should +# be configured to provide at least as many connections as the number of +# threads. This includes Active Record's `pool` parameter in `database.yml`. +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch("PORT", 3000) + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart + +# Run the Solid Queue supervisor inside of Puma for single-server deployments +plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] + +# Specify the PID file. Defaults to tmp/pids/server.pid in development. +# In other environments, only set the PID file if requested. +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/config/queue.yml b/config/queue.yml new file mode 100644 index 0000000000..9eace59c41 --- /dev/null +++ b/config/queue.yml @@ -0,0 +1,18 @@ +default: &default + dispatchers: + - polling_interval: 1 + batch_size: 500 + workers: + - queues: "*" + threads: 3 + processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> + polling_interval: 0.1 + +development: + <<: *default + +test: + <<: *default + +production: + <<: *default diff --git a/config/recurring.yml b/config/recurring.yml new file mode 100644 index 0000000000..b4207f9b07 --- /dev/null +++ b/config/recurring.yml @@ -0,0 +1,15 @@ +# examples: +# periodic_cleanup: +# class: CleanSoftDeletedRecordsJob +# queue: background +# args: [ 1000, { batch_size: 500 } ] +# schedule: every hour +# periodic_cleanup_with_command: +# command: "SoftDeletedRecord.due.delete_all" +# priority: 2 +# schedule: at 5am every day + +production: + clear_solid_queue_finished_jobs: + command: "SolidQueue::Job.clear_finished_in_batches(sleep_between_batches: 0.3)" + schedule: every hour at minute 12 diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000000..48254e88ed --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,14 @@ +Rails.application.routes.draw do + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. + # Can be used by load balancers and uptime monitors to verify that the app is live. + get "up" => "rails/health#show", as: :rails_health_check + + # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) + # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest + # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker + + # Defines the root path route ("/") + # root "posts#index" +end diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 0000000000..4942ab6694 --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/db/cable_schema.rb b/db/cable_schema.rb new file mode 100644 index 0000000000..23666604a5 --- /dev/null +++ b/db/cable_schema.rb @@ -0,0 +1,11 @@ +ActiveRecord::Schema[7.1].define(version: 1) do + create_table "solid_cable_messages", force: :cascade do |t| + t.binary "channel", limit: 1024, null: false + t.binary "payload", limit: 536870912, null: false + t.datetime "created_at", null: false + t.integer "channel_hash", limit: 8, null: false + t.index ["channel"], name: "index_solid_cable_messages_on_channel" + t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash" + t.index ["created_at"], name: "index_solid_cable_messages_on_created_at" + end +end diff --git a/db/cache_schema.rb b/db/cache_schema.rb new file mode 100644 index 0000000000..81a410d188 --- /dev/null +++ b/db/cache_schema.rb @@ -0,0 +1,12 @@ +ActiveRecord::Schema[7.2].define(version: 1) do + create_table "solid_cache_entries", force: :cascade do |t| + t.binary "key", limit: 1024, null: false + t.binary "value", limit: 536870912, null: false + t.datetime "created_at", null: false + t.integer "key_hash", limit: 8, null: false + t.integer "byte_size", limit: 4, null: false + t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size" + t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size" + t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true + end +end diff --git a/db/queue_schema.rb b/db/queue_schema.rb new file mode 100644 index 0000000000..85194b6a88 --- /dev/null +++ b/db/queue_schema.rb @@ -0,0 +1,129 @@ +ActiveRecord::Schema[7.1].define(version: 1) do + create_table "solid_queue_blocked_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.string "concurrency_key", null: false + t.datetime "expires_at", null: false + t.datetime "created_at", null: false + t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release" + t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance" + t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true + end + + create_table "solid_queue_claimed_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.bigint "process_id" + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true + t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id" + end + + create_table "solid_queue_failed_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.text "error" + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true + end + + create_table "solid_queue_jobs", force: :cascade do |t| + t.string "queue_name", null: false + t.string "class_name", null: false + t.text "arguments" + t.integer "priority", default: 0, null: false + t.string "active_job_id" + t.datetime "scheduled_at" + t.datetime "finished_at" + t.string "concurrency_key" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id" + t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name" + t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at" + t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering" + t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting" + end + + create_table "solid_queue_pauses", force: :cascade do |t| + t.string "queue_name", null: false + t.datetime "created_at", null: false + t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true + end + + create_table "solid_queue_processes", force: :cascade do |t| + t.string "kind", null: false + t.datetime "last_heartbeat_at", null: false + t.bigint "supervisor_id" + t.integer "pid", null: false + t.string "hostname" + t.text "metadata" + t.datetime "created_at", null: false + t.string "name", null: false + t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at" + t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true + t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id" + end + + create_table "solid_queue_ready_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true + t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all" + t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue" + end + + create_table "solid_queue_recurring_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "task_key", null: false + t.datetime "run_at", null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true + t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true + end + + create_table "solid_queue_recurring_tasks", force: :cascade do |t| + t.string "key", null: false + t.string "schedule", null: false + t.string "command", limit: 2048 + t.string "class_name" + t.text "arguments" + t.string "queue_name" + t.integer "priority", default: 0 + t.boolean "static", default: true, null: false + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true + t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static" + end + + create_table "solid_queue_scheduled_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.datetime "scheduled_at", null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true + t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all" + end + + create_table "solid_queue_semaphores", force: :cascade do |t| + t.string "key", null: false + t.integer "value", default: 1, null: false + t.datetime "expires_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at" + t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value" + t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true + end + + add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000000..4fbd6ed970 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,9 @@ +# This file should ensure the existence of records required to run the application in every environment (production, +# development, test). The code here should be idempotent so that it can be executed at any point in every environment. +# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). +# +# Example: +# +# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| +# MovieGenre.find_or_create_by!(name: genre_name) +# end diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/log/.keep b/log/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/400.html b/public/400.html new file mode 100644 index 0000000000..282dbc8cc9 --- /dev/null +++ b/public/400.html @@ -0,0 +1,114 @@ + + + + + + + The server cannot process the request due to a client error (400 Bad Request) + + + + + + + + + + + + + +
+
+ +
+
+

The server cannot process the request due to a client error. Please check the request and try again. If you’re the application owner check the logs for more information.

+
+
+ + + + diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000000..c0670bc877 --- /dev/null +++ b/public/404.html @@ -0,0 +1,114 @@ + + + + + + + The page you were looking for doesn’t exist (404 Not found) + + + + + + + + + + + + + +
+
+ +
+
+

The page you were looking for doesn’t exist. You may have mistyped the address or the page may have moved. If you’re the application owner check the logs for more information.

+
+
+ + + + diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html new file mode 100644 index 0000000000..9532a9ccd0 --- /dev/null +++ b/public/406-unsupported-browser.html @@ -0,0 +1,114 @@ + + + + + + + Your browser is not supported (406 Not Acceptable) + + + + + + + + + + + + + +
+
+ +
+
+

Your browser is not supported.
Please upgrade your browser to continue.

+
+
+ + + + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000000..8bcf06014f --- /dev/null +++ b/public/422.html @@ -0,0 +1,114 @@ + + + + + + + The change you wanted was rejected (422 Unprocessable Entity) + + + + + + + + + + + + + +
+
+ +
+
+

The change you wanted was rejected. Maybe you tried to change something you didn’t have access to. If you’re the application owner check the logs for more information.

+
+
+ + + + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000000..d77718c3a4 --- /dev/null +++ b/public/500.html @@ -0,0 +1,114 @@ + + + + + + + We’re sorry, but something went wrong (500 Internal Server Error) + + + + + + + + + + + + + +
+
+ +
+
+

We’re sorry, but something went wrong.
If you’re the application owner check the logs for more information.

+
+
+ + + + diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c4c9dbfbbd2f7c1421ffd5727188146213abbcef GIT binary patch literal 4166 zcmd6qU;WFw?|v@m)Sk^&NvB8tcujdV-r1b=i(NJxn&7{KTb zX$3(M+3TP2o^#KAo{#tIjl&t~(8D-k004kqPglzn0HFG(Q~(I*AKsD#M*g7!XK0T7 zN6P7j>HcT8rZgKl$v!xr806dyN19Bd4C0x_R*I-a?#zsTvb_89cyhuC&T**i|Rc zq5b8M;+{8KvoJ~uj9`u~d_f6`V&3+&ZX9x5pc8s)d175;@pjm(?dapmBcm0&vl9+W zx1ZD2o^nuyUHWj|^A8r>lUorO`wFF;>9XL-Jy!P}UXC{(z!FO%SH~8k`#|9;Q|eue zqWL0^Bp(fg_+Pkm!fDKRSY;+^@BF?AJE zCUWpXPst~hi_~u)SzYBDZroR+Z4xeHIlm_3Yc_9nZ(o_gg!jDgVa=E}Y8uDgem9`b zf=mfJ_@(BXSkW53B)F2s!&?_R4ptb1fYXlF++@vPhd=marQgEGRZS@B4g1Mu?euknL= z67P~tZ?*>-Hmi7GwlisNHHJDku-dSm7g@!=a}9cSL6Pa^w^2?&?$Oi8ibrr>w)xqx zOH_EMU@m05)9kuNR>>4@H%|){U$^yvVQ(YgOlh;5oU_-vivG-p4=LrN-k7D?*?u1u zsWly%tfAzKd6Fb=`eU2un_uaTXmcT#tlOL+aRS=kZZf}A7qT8lvcTx~7j` z*b>=z)mwg7%B2_!D0!1IZ?Nq{^Y$uI4Qx*6T!E2Col&2{k?ImCO=dD~A&9f9diXy^$x{6CwkBimn|1E09 zAMSezYtiL?O6hS37KpvDM?22&d{l)7h-!F)C-d3j8Z`c@($?mfd{R82)H>Qe`h{~G z!I}(2j(|49{LR?w4Jspl_i!(4T{31|dqCOpI52r5NhxYV+cDAu(xp*4iqZ2e-$YP= zoFOPmm|u*7C?S{Fp43y+V;>~@FFR76bCl@pTtyB93vNWy5yf;HKr8^0d7&GVIslYm zo3Tgt@M!`8B6IW&lK{Xk>%zp41G%`(DR&^u z5^pwD4>E6-w<8Kl2DzJ%a@~QDE$(e87lNhy?-Qgep!$b?5f7+&EM7$e>|WrX+=zCb z=!f5P>MxFyy;mIRxjc(H*}mceXw5a*IpC0PEYJ8Y3{JdoIW)@t97{wcUB@u+$FCCO z;s2Qe(d~oJC^`m$7DE-dsha`glrtu&v&93IZadvl_yjp!c89>zo;Krk+d&DEG4?x$ zufC1n+c1XD7dolX1q|7}uelR$`pT0Z)1jun<39$Sn2V5g&|(j~Z!wOddfYiZo7)A< z!dK`aBHOOk+-E_xbWCA3VR-+o$i5eO9`rMI#p_0xQ}rjEpGW;U!&&PKnivOcG(|m9 z!C8?WC6nCXw25WVa*eew)zQ=h45k8jSIPbq&?VE{oG%?4>9rwEeB4&qe#?-y_es4c|7ufw%+H5EY#oCgv!Lzv291#-oNlX~X+Jl5(riC~r z=0M|wMOP)Tt8@hNg&%V@Z9@J|Q#K*hE>sr6@oguas9&6^-=~$*2Gs%h#GF@h)i=Im z^iKk~ipWJg1VrvKS;_2lgs3n1zvNvxb27nGM=NXE!D4C!U`f*K2B@^^&ij9y}DTLB*FI zEnBL6y{jc?JqXWbkIZd7I16hA>(f9T!iwbIxJj~bKPfrO;>%*5nk&Lf?G@c2wvGrY&41$W{7HM9+b@&XY@>NZM5s|EK_Dp zQX60CBuantx>|d#DsaZ*8MW(we|#KTYZ=vNa#d*DJQe6hr~J6{_rI#?wi@s|&O}FR zG$kfPxheXh1?IZ{bDT-CWB4FTvO-k5scW^mi8?iY5Q`f8JcnnCxiy@m@D-%lO;y0pTLhh6i6l@x52j=#^$5_U^os}OFg zzdHbo(QI`%9#o*r8GCW~T3UdV`szO#~)^&X_(VW>o~umY9-ns9-V4lf~j z`QBD~pJ4a#b`*6bJ^3RS5y?RAgF7K5$ll97Y8#WZduZ`j?IEY~H(s^doZg>7-tk*t z4_QE1%%bb^p~4F5SB$t2i1>DBG1cIo;2(xTaj*Y~hlM{tSDHojL-QPg%Mo%6^7FrpB*{ z4G0@T{-77Por4DCMF zB_5Y~Phv%EQ64W8^GS6h?x6xh;w2{z3$rhC;m+;uD&pR74j+i22P5DS-tE8ABvH(U~indEbBUTAAAXfHZg5QpB@TgV9eI<)JrAkOI z8!TSOgfAJiWAXeM&vR4Glh;VxH}WG&V$bVb`a`g}GSpwggti*&)taV1@Ak|{WrV|5 zmNYx)Ans=S{c52qv@+jmGQ&vd6>6yX6IKq9O$3r&0xUTdZ!m1!irzn`SY+F23Rl6# zFRxws&gV-kM1NX(3(gnKpGi0Q)Dxi~#?nyzOR9!en;Ij>YJZVFAL*=R%7y%Mz9hU% zs>+ZB?qRmZ)nISx7wxY)y#cd$iaC~{k0avD>BjyF1q^mNQ1QcwsxiTySe<6C&cC6P zE`vwO9^k-d`9hZ!+r@Jnr+MF*2;2l8WjZ}DrwDUHzSF{WoG zucbSWguA!3KgB3MU%HH`R;XqVv0CcaGq?+;v_A5A2kpmk5V%qZE3yzQ7R5XWhq=eR zyUezH=@V)y>L9T-M-?tW(PQYTRBKZSVb_!$^H-Pn%ea;!vS_?M<~Tm>_rWIW43sPW z=!lY&fWc1g7+r?R)0p8(%zp&vl+FK4HRkns%BW+Up&wK8!lQ2~bja|9bD12WrKn#M zK)Yl9*8$SI7MAwSK$%)dMd>o+1UD<2&aQMhyjS5R{-vV+M;Q4bzl~Z~=4HFj_#2V9 zB)Gfzx3ncy@uzx?yzi}6>d%-?WE}h7v*w)Jr_gBl!2P&F3DX>j_1#--yjpL%<;JMR z*b70Gr)MMIBWDo~#<5F^Q0$VKI;SBIRneuR7)yVsN~A9I@gZTXe)E?iVII+X5h0~H zx^c(fP&4>!*q>fb6dAOC?MI>Cz3kld#J*;uik+Ps49cwm1B4 zZc1|ZxYyTv;{Z!?qS=D)sgRKx^1AYf%;y_V&VgZglfU>d+Ufk5&LV$sKv}Hoj+s; xK3FZRYdhbXT_@RW*ff3@`D1#ps#~H)p+y&j#(J|vk^lW{fF9OJt5(B-_&*Xgn9~3N literal 0 HcmV?d00001 diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 0000000000..04b34bf83f --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000000..c19f78ab68 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/script/.keep b/script/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/storage/.keep b/storage/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb new file mode 100644 index 0000000000..cee29fd214 --- /dev/null +++ b/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ] +end diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/helpers/.keep b/test/helpers/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/system/.keep b/test/system/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000000..0c22470ec1 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,15 @@ +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" +require "rails/test_help" + +module ActiveSupport + class TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... + end +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tmp/pids/.keep b/tmp/pids/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tmp/storage/.keep b/tmp/storage/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/.keep b/vendor/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/javascript/.keep b/vendor/javascript/.keep new file mode 100644 index 0000000000..e69de29bb2 From 22a463cf4aad1371308c66c7a34cfd9daaa2c3d6 Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Thu, 13 Nov 2025 19:34:38 -0300 Subject: [PATCH 02/42] FEAT(add): Cucumber config --- Gemfile | 9 +++- Gemfile.lock | 49 +++++++++++++++++++++ bin/cucumber | 11 +++++ config/cucumber.yml | 8 ++++ config/environments/development.rb | 4 ++ config/environments/test.rb | 4 ++ features/step_definitions/.keep | 0 features/support/env.rb | 53 +++++++++++++++++++++++ lib/tasks/cucumber.rake | 69 ++++++++++++++++++++++++++++++ 9 files changed, 205 insertions(+), 2 deletions(-) create mode 100755 bin/cucumber create mode 100644 config/cucumber.yml create mode 100644 features/step_definitions/.keep create mode 100644 features/support/env.rb create mode 100644 lib/tasks/cucumber.rake diff --git a/Gemfile b/Gemfile index ed45b5b828..03a0aba365 100644 --- a/Gemfile +++ b/Gemfile @@ -56,8 +56,13 @@ group :development do gem "web-console" end +# Testing gems group :test do - # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + # Rails default system testing gem "capybara" gem "selenium-webdriver" -end + + # Cucumber support + gem "cucumber-rails", require: false + gem "database_cleaner-active_record" +end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 75d2d41720..aedc81f092 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,10 +99,44 @@ GEM concurrent-ruby (1.3.5) connection_pool (2.5.4) crass (1.0.6) + cucumber (10.1.1) + base64 (~> 0.2) + builder (~> 3.2) + cucumber-ci-environment (> 9, < 11) + cucumber-core (> 15, < 17) + cucumber-cucumber-expressions (> 17, < 19) + cucumber-html-formatter (> 20.3, < 22) + diff-lcs (~> 1.5) + logger (~> 1.6) + mini_mime (~> 1.1) + multi_test (~> 1.1) + sys-uname (~> 1.3) + cucumber-ci-environment (10.0.1) + cucumber-core (15.3.0) + cucumber-gherkin (> 27, < 35) + cucumber-messages (> 26, < 30) + cucumber-tag-expressions (> 5, < 9) + cucumber-cucumber-expressions (18.0.1) + bigdecimal + cucumber-gherkin (34.0.0) + cucumber-messages (> 25, < 29) + cucumber-html-formatter (21.15.1) + cucumber-messages (> 19, < 28) + cucumber-messages (27.2.0) + cucumber-rails (4.0.0) + capybara (>= 3.25, < 4) + cucumber (>= 7, < 11) + railties (>= 6.1, < 9) + cucumber-tag-expressions (8.0.0) + database_cleaner-active_record (2.2.2) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0) + database_cleaner-core (2.0.1) date (3.5.0) debug (1.11.0) irb (~> 1.10) reline (>= 0.3.8) + diff-lcs (1.6.2) dotenv (3.1.8) drb (2.2.3) ed25519 (1.4.0) @@ -110,6 +144,14 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -155,9 +197,11 @@ GEM net-smtp marcel (1.1.0) matrix (0.4.3) + memoist3 (1.0.0) mini_mime (1.1.5) minitest (5.26.1) msgpack (1.8.0) + multi_test (1.1.0) net-imap (0.5.12) date net-protocol @@ -329,6 +373,9 @@ GEM stimulus-rails (1.3.4) railties (>= 6.0.0) stringio (3.1.8) + sys-uname (1.4.1) + ffi (~> 1.1) + memoist3 (~> 1.0.0) thor (1.4.0) thruster (0.1.16) thruster (0.1.16-aarch64-linux) @@ -377,6 +424,8 @@ DEPENDENCIES bootsnap brakeman capybara + cucumber-rails + database_cleaner-active_record debug importmap-rails jbuilder diff --git a/bin/cucumber b/bin/cucumber new file mode 100755 index 0000000000..eb5e962e86 --- /dev/null +++ b/bin/cucumber @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first +if vendored_cucumber_bin + load File.expand_path(vendored_cucumber_bin) +else + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'cucumber' + load Cucumber::BINARY +end diff --git a/config/cucumber.yml b/config/cucumber.yml new file mode 100644 index 0000000000..47a4663ae2 --- /dev/null +++ b/config/cucumber.yml @@ -0,0 +1,8 @@ +<% +rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" +rerun = rerun.strip.gsub /\s/, ' ' +rerun_opts = rerun.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" +std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags 'not @wip'" +%> +default: <%= std_opts %> features +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags 'not @wip' diff --git a/config/environments/development.rb b/config/environments/development.rb index 4cc21c4ebe..1a0bf09e40 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,6 +1,10 @@ require "active_support/core_ext/integer/time" Rails.application.configure do + # Configure 'rails notes' to inspect Cucumber files + config.annotations.register_directories('features') + config.annotations.register_extensions('feature') { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + # Settings specified here will take precedence over those in config/application.rb. # Make code changes take effect immediately without server restart. diff --git a/config/environments/test.rb b/config/environments/test.rb index c2095b1174..e6b5c1b020 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -4,6 +4,10 @@ # and recreated between test runs. Don't rely on the data there! Rails.application.configure do + # Configure 'rails notes' to inspect Cucumber files + config.annotations.register_directories('features') + config.annotations.register_extensions('feature') { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + # Settings specified here will take precedence over those in config/application.rb. # While tests run files are not watched, reloading is not necessary. diff --git a/features/step_definitions/.keep b/features/step_definitions/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100644 index 0000000000..3b97d14087 --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,53 @@ +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. +# It is recommended to regenerate this file in the future when you upgrade to a +# newer version of cucumber-rails. Consider adding your own code to a new file +# instead of editing this one. Cucumber will automatically load all features/**/*.rb +# files. + + +require 'cucumber/rails' + +# By default, any exception happening in your Rails application will bubble up +# to Cucumber so that your scenario will fail. This is a different from how +# your application behaves in the production environment, where an error page will +# be rendered instead. +# +# Sometimes we want to override this default behaviour and allow Rails to rescue +# exceptions and display an error page (just like when the app is running in production). +# Typical scenarios where you want to do this is when you test your error pages. +# There are two ways to allow Rails to rescue exceptions: +# +# 1) Tag your scenario (or feature) with @allow-rescue +# +# 2) Set the value below to true. Beware that doing this globally is not +# recommended as it will mask a lot of errors for you! +# +ActionController::Base.allow_rescue = false + +# Remove/comment out the lines below if your app doesn't have a database. +# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. +begin + DatabaseCleaner.strategy = :transaction +rescue NameError + raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." +end + +# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. +# See the DatabaseCleaner documentation for details. Example: +# +# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do +# # { except: [:widgets] } may not do what you expect here +# # as Cucumber::Rails::Database.javascript_strategy overrides +# # this setting. +# DatabaseCleaner.strategy = :truncation +# end +# +# Before('not @no-txn', 'not @selenium', 'not @culerity', 'not @celerity', 'not @javascript') do +# DatabaseCleaner.strategy = :transaction +# end +# + +# Possible values are :truncation and :transaction +# The :transaction strategy is faster, but might give you threading problems. +# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature +Cucumber::Rails::Database.javascript_strategy = :truncation diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake new file mode 100644 index 0000000000..0caa4d2553 --- /dev/null +++ b/lib/tasks/cucumber.rake @@ -0,0 +1,69 @@ +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. +# It is recommended to regenerate this file in the future when you upgrade to a +# newer version of cucumber-rails. Consider adding your own code to a new file +# instead of editing this one. Cucumber will automatically load all features/**/*.rb +# files. + + +unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks + +vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first +$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? + +begin + require 'cucumber/rake/task' + + namespace :cucumber do + Cucumber::Rake::Task.new({ok: 'test:prepare'}, 'Run features that should pass') do |t| + t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. + t.fork = true # You may get faster startup if you set this to false + t.profile = 'default' + end + + Cucumber::Rake::Task.new({wip: 'test:prepare'}, 'Run features that are being worked on') do |t| + t.binary = vendored_cucumber_bin + t.fork = true # You may get faster startup if you set this to false + t.profile = 'wip' + end + + Cucumber::Rake::Task.new({rerun: 'test:prepare'}, 'Record failing features and run only them if any exist') do |t| + t.binary = vendored_cucumber_bin + t.fork = true # You may get faster startup if you set this to false + t.profile = 'rerun' + end + + desc 'Run all features' + task all: [:ok, :wip] + + task :statsetup do + require 'rails/code_statistics' + ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features') + ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features') + end + + end + + desc 'Alias for cucumber:ok' + task cucumber: 'cucumber:ok' + + task default: :cucumber + + task features: :cucumber do + STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" + end + + # In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon. + task 'test:prepare' do + end + + task stats: 'cucumber:statsetup' + + +rescue LoadError + desc 'cucumber rake task not available (cucumber not installed)' + task :cucumber do + abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' + end +end + +end From b336748ebb24ec168032ac818e7102ac6cc9cd58 Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Thu, 13 Nov 2025 19:38:43 -0300 Subject: [PATCH 03/42] Feat(add) docker compose file --- docker-compose.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..da38d35673 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3.9" + +services: + web: + build: . + command: ./bin/dev + volumes: + - .:/rails + ports: + - "3000:3000" From 5b500274c6d63a95a9fc1160a57f899e4e709a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Sun, 16 Nov 2025 11:55:14 -0300 Subject: [PATCH 04/42] Add files via upload --- Wiki.md | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Wiki.md diff --git a/Wiki.md b/Wiki.md new file mode 100644 index 0000000000..1e009d7e9e --- /dev/null +++ b/Wiki.md @@ -0,0 +1,107 @@ +# 📝 Wiki do Projeto – Sprint 1 +**Grupo 1 – Engenharia de Software** +**Integrantes:** + +| Nome | Matrícula | +| :--- | :--- | +| Caroline | 232050975 | +| Célio | 211010350 | +| Luís Filipe | 190091975 | +| Mário | 231035778 | + +--- + +# 📌 Nome do Projeto +**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC Pipipipópópó(ainda a ser editado)** + +--- + +# 📌 Escopo do Projeto +O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. +O projeto contempla funcionalidades de cadastro de usuários, criação de tarefas, acompanhamento de entregas e visualização de desempenho. + +--- + +# 🔰 Papéis na Sprint 1 + +## 🧑‍💼 Scrum Master +> **Função:** Responsável por garantir que a equipe siga a metodologia Scrum. Remove impedimentos que possam atrapalhar os desenvolvedores, facilita as cerimônias (Reuniões Diárias, Planejamento, Revisão e Retrospectiva) e protege o time de interrupções externas. +**Fulano** +### Funções: +- Facilitar as cerimônias da Sprint (Planning, Review, Retrospective). +- Remover impedimentos enfrentados pela equipe. +- Assegurar que o time siga os princípios ágeis. + +--- + +## 🧑‍💻 Product Owner +> **Função:** O "dono do produto". É a voz do cliente/usuário. Sua principal responsabilidade é definir *o que* será construído, criar e priorizar os itens do Product Backlog (as funcionalidades) para maximizar o valor entregue pela equipe a cada Sprint. + +**Fulana (00000000)** +### Funções: +- Definir e priorizar o Product Backlog. +- Garantir que as funcionalidades entreguem valor ao usuário final. +- Esclarecer dúvidas sobre requisitos. + +--- + +# 🚀 Funcionalidades da Sprint 1 + +A Sprint 1 tem como foco as **funcionalidades essenciais** relacionadas ao cadastro e acesso de usuários. + +## 📦 Funcionalidade 1 – Cadastro de Usuário +**Regra de Negócio:** +- O sistema deve validar e-mail único. +- Senha deve ter pelo menos 8 caracteres. +- O usuário só pode acessar o sistema após confirmar o e-mail. + +**Responsável:** Bombardilno crocodilo +**Histórias:** +- **US01**: “Como usuário, quero criar uma conta usando e-mail e senha para acessar o sistema.” + - **Story Points:** x +- **US02**: “Como usuário, quero receber um e-mail de confirmação para ativar minha conta.” + - **Story Points:** x + +--- + +## 📦 Funcionalidade 2 – Login no Sistema +**Regra de Negócio:** +- O sistema deve bloquear após 5 tentativas falhas consecutivas. +- O login só será autorizado caso o e-mail esteja verificado. + +**Responsável:** Bombardilno crocodilo +**Histórias:** +- **US03**: “Como usuário, quero fazer login com meu e-mail e senha para acessar o sistema.” + - **Story Points:** x +- **US04**: “Como usuário, quero recuperar minha senha caso eu a esqueça.” + - **Story Points:** x + +--- + +# 📊 Métrica Velocity da Sprint 1 + +| História | Pontos | +|----------|--------| +| US01 | X | +| US02 | X | +| US03 | X | +| US04 | X | +| **Total** | **x story points** | + +A *velocity* da Sprint 1 é **x pontos**. + +--- + +# 🌿 Política de Branching Utilizada pelo Grupo + + +--- + +# 📌 Resumo +Esta página da Wiki apresenta: +- Integrantes do grupo e papéis na Sprint +- Funcionalidades planejadas +- Regras de negócio +- Responsáveis +- Pontuação das histórias (Velocity) +- Política de branching adotada From fb37d77ef63264f35e249290218087bf2247cfa6 Mon Sep 17 00:00:00 2001 From: Carol <232050975@aluno.unb.br> Date: Mon, 17 Nov 2025 10:09:44 -0300 Subject: [PATCH 05/42] =?UTF-8?q?Especifica=C3=A7=C3=A3o=20dos=20BDDs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/admin/atualizar_dados.feature | 66 +++++++++++++++++++++ features/admin/gerenciar_relatorios.feature | 28 +++++++++ features/admin/importar_dados.feature | 48 +++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 features/admin/atualizar_dados.feature create mode 100644 features/admin/gerenciar_relatorios.feature create mode 100644 features/admin/importar_dados.feature diff --git a/features/admin/atualizar_dados.feature b/features/admin/atualizar_dados.feature new file mode 100644 index 0000000000..1e10d4ba9a --- /dev/null +++ b/features/admin/atualizar_dados.feature @@ -0,0 +1,66 @@ +# language: pt-br + +Funcionalidade: Atualização da base de dados por importação de JSON do SIGAA + + Como um administrador do sistema + Eu quero fazer o upload de um (ou mais) arquivo JSON contendo os dados das disciplinas, turmas e alunos matriculados + A fim de atualizar o sistema com as turmas do semestre e garantir que apenas os alunos corretos possam avaliar seus respectivos professores. + +Cenário: Admin importa JSON de um novo semestre + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E eu tenho os arquivos "disciplinas_2021.2.json" e "turmas_2021.2.json" + Quando eu seleciono os arquivos "disciplinas_2021.2.json" e "turmas_2021.2.json" + E importo-os para o sistema + Então eu devo ver a mensagem "Importação concluída." + E a disciplina "BANCOS DE DADOS" (CIC0097) deve existir no sistema + E a aluna "Ana Clara Jordao Perna" (190084006) deve estar matriculada na turma "TA" de "CIC0097" + + +Cenário: Admin importa JSON que atualiza o email de um aluno + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E existe uma aluna "Ana Clara Jordao Perna" (190084006) com o email "acjpjvjp@gmail.com" + E eu tenho um arquivo "turmas_correcao.json" onde o aluno "190484006" agora tem o email "ana.clara@aluno.unb.br" + Quando eu seleciono o arquivo "turmas_correcao.json" + E importo-o ao sistema + Então eu devo ver a mensagem "Importação concluída." + E a aluna (190084006) deve ter o email "ana.clara@aluno.unb.br" no banco de dados + E não deve existir um novo aluno no sistema + +Cenário: Admin tenta importar um arquivo que não é JSON + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + Quando eu seleciono um arquivo "documento.csv" para importaçao de dados + E importo-o ao sistema + Então eu devo continuar na página que contém o botão "Importar dados" + E eu devo ver a mensagem de erro "Formato de arquivo inválido. Por favor, envie um arquivo .json." + +Cenário: Admin importa JSON de turma com chave "matricula" faltando + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E eu tenho um arquivo "turmas_sem_matricula.json" onde um objeto "discente" não possui a chave "matricula" + Quando eu seleciono o arquivo "turmas_sem_matricula.json" para importação de dados + E importo-o ao sistema + Então eu devo continuar na página que contém o botão "Importar dados" + E eu devo ver a mensagem de erro "Erro na importação: O arquivo JSON é inválido." + + +Cenário: Admin importa um arquivo JSON com sintaxe quebrada + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E eu tenho um arquivo "json_errado.json" (que possui um erro de sintaxe, como uma vírgula extra) + Quando eu seleciono o arquivo "json_errado.json" para importação de dados + E importo-o ao sistema + Então eu devo continuar na página que contém o botão "Importar dados" + E eu devo ver a mensagem de erro "Erro: O arquivo não é um JSON válido." + + +Cenário: Admin importa JSON com tipo de dado inválido para matrícula + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E eu tenho um arquivo "turmas_tipo_errado.json" onde a "matricula" de um aluno é o texto "matricula" em vez de um número + Quando eu seleciono o arquivo "turmas_tipo_errado.json" para importação de dados + E importo-o ao sistema + Então eu devo continuar na página que contém o botão "Importar dados" + E eu devo ver a mensagem de erro "Erro na importação." \ No newline at end of file diff --git a/features/admin/gerenciar_relatorios.feature b/features/admin/gerenciar_relatorios.feature new file mode 100644 index 0000000000..56b2b263ff --- /dev/null +++ b/features/admin/gerenciar_relatorios.feature @@ -0,0 +1,28 @@ +# language: pt-br + +Funcionalidade: Visualização e Download de Resultados de Avaliação + Como um administrador + Eu quero baixar um arquivo CSV contendo os resultados de um formulário + A fim de avaliar o desempenho das turmas + +Cenário: Admin baixa CSV de uma turma com respostas + Dado que eu estou logado como "admin@sistema.com" + E eu navego para a página "Gerenciamento" + E eu clico em "Resultados" + E eu estou na tela "Gerenciamento - Resultados" + Quando eu clico no bloco da turma "BANCOS DE DADOS (CIC0097) - Prof. Joao" + Então eu devo baixar um arquivo chamado "resultados_CIC0097_ProfJoao.csv" + +Cenário: Admin tenta ver resultados de uma turma sem respostas + Dado que eu estou logado como "admin@sistema.com" + E eu estou na tela "Gerenciamento - Resultados" + E a turma "ENGENHARIA DE SOFTWARE (CIC0105) - Prof. Genaina" possui 0 respostas de avaliação + Quando eu clico no bloco da turma "ENGENHARIA DE SOFTWARE (CIC0105) - Prof. Genaina" + Então deve exibir a mensagem "Este formulário ainda não possui respostas" + E não efetuar nenhum download de aruivo CSV. + +Cenário: Professor (não-admin) tenta acessar a página de resultados diretamente pela URL + Dado que eu estou logado como "professor.comum@sistema.com" (que não é admin) + E eu não vejo o link para a página "Gerenciamento" no meu menu + Quando eu tento acessar a URL "/gerenciamento/resultados" diretamente no meu navegador + Então eu devo ser redirecionado para a minha página inicial (ou "Dashboard") \ No newline at end of file diff --git a/features/admin/importar_dados.feature b/features/admin/importar_dados.feature new file mode 100644 index 0000000000..a31421e252 --- /dev/null +++ b/features/admin/importar_dados.feature @@ -0,0 +1,48 @@ +# language: pt-br + +Funcionalidade: Alimentação inicial da base de dados com JSON do SIGAA + + Como um administrador + Eu quero importar dados de turmas, matérias e participantes do SIGAA (caso não existam na base de dados atual) + A fim de alimentar a base de dados do sistema. + +Cenário: Admin importa dados em um sistema vazio + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E o banco de dados não contém nenhuma disciplina ou aluno + E eu tenho um arquivo "disciplinas_2021.2.json" (com a disciplina "BANCOS DE DADOS") + E eu tenho um arquivo "turmas_2021.2.json" (com o aluno "Ana Clara Jordao Perna") + Quando eu seleciono os arquivos "disciplinas_2021.2.json" e "turmas_2021.2.json" + E importo-os ao sistema + Então eu devo ver a mensagem "Importação concluída." + E a disciplina "BANCOS DE DADOS" (CIC0097) deve existir no sistema + E o aluno "Ana Clara Jordao Perna" (190084006) deve existir no sistema + +Cenário: Admin importa dados que já existem na base + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E já existe uma disciplina "BANCOS DE DADOS" (CIC0097) no sistema + E já existe o aluno "Ana Clara Jordao Perna" (190084006) + E eu tenho um arquivo "turmas_2021.2_repetido.json" que contém os mesmos dados + Quando eu seleciono o arquivo "turmas_2021.2_repetido.json" + E impoto-o ao sistema + Então eu devo ver a mensagem "Importação concluída." + E deve haver apenas 1 aluno com a matrícula "190084006" no sistema + +Cenário: Admin tenta alimentar a base com um arquivo que não é JSON + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E o banco de dados está vazio + Quando eu seleciono um arquivo "lista_de_alunos.pdf" + E importo-o ao sistema + Então devo ver a mensagem de erro "Formato de arquivo inválido. Por favor, envie um arquivo .json." + +Cenário: Admin importa JSON de turma com a chave "matricula" faltando + Dado que eu estou logado como "admin@sistema.com" + E eu estou na página que contém o botão "Importar dados" + E eu tenho um arquivo "turmas_sem_matricula.json" onde um "discente" não possui a chave "matricula" + Quando eu seleciono o arquivo "turmas_sem_matricula.json" + E importo-o ao sistema + Então eu devo ver a mensagem de erro "Erro na importação: O arquivo JSON é inválido." + + From ad8f67a37ae21d85b8f2a08b3e53820026f0822e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Mon, 17 Nov 2025 11:29:15 -0300 Subject: [PATCH 06/42] =?UTF-8?q?Add=20-=20redefini=C3=A7=C3=A3o=20de=20se?= =?UTF-8?q?nha=20-=20feature=20scenario?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/login/redefinicao_senha.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 features/login/redefinicao_senha.feature diff --git a/features/login/redefinicao_senha.feature b/features/login/redefinicao_senha.feature new file mode 100644 index 0000000000..0f9af74dc8 --- /dev/null +++ b/features/login/redefinicao_senha.feature @@ -0,0 +1,22 @@ +Funcionalidade: Redefinição de senha + Como um Usuário + Eu quero redefinir uma senha para o meu usuário a partir do e-mail recebido + A fim de recuperar o meu acesso ao sistema + +Cenário: Usuário solicita redefinição com e-mail válido (Caminho Feliz) + Dado que eu estou na página de "Login" + E existe um usuário cadastrado com o e-mail "usuario_valido@alias" + Quando eu clico no link "Esqueci minha senha" + E eu preencho o campo "E-mail" com "usuario_valido@alias" + E clico no botão "Solicitar redefinição" + Então eu devo ver a mensagem "Um e-mail de redefinição foi enviado para sua caixa de entrada." + E um e-mail com um link de redefinição deve ser enviado para "usuario_valido@alias" + +Cenário: Usuário solicita redefinição com e-mail não cadastrado (Caminho Triste) + Dado que eu estou na página de "Login" + E não existe um usuário cadastrado com o e-mail "usuario_valido@alias" + Quando eu clico no link "Esqueci minha senha" + E eu preencho o campo "E-mail" com "usuario_valido@alias" + E clico no botão "Solicitar redefinição" + Então eu devo ver a mensagem "Se este e-mail estiver cadastrado, um link será enviado." + E nenhum e-mail de redefinição deve ser enviado From 62d88c9c551a5b39f71a6dc6aae39c4d3d2272fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Mon, 17 Nov 2025 11:33:14 -0300 Subject: [PATCH 07/42] Add scenarios for weak password validations --- features/login/definicao_senha.feature | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 features/login/definicao_senha.feature diff --git a/features/login/definicao_senha.feature b/features/login/definicao_senha.feature new file mode 100644 index 0000000000..91cd821fd4 --- /dev/null +++ b/features/login/definicao_senha.feature @@ -0,0 +1,36 @@ +Funcionalidade: Definição inicial de senha + Como um Usuário + Eu quero definir uma senha para o meu usuário a partir do e-mail do sistema de solicitação de cadastro + A fim de acessar o sistema + +Cenário: Usuário define uma senha válida pela primeira vez (Caminho Feliz) + Dado que eu acessei a página "Definir Senha" através de um link de cadastro válido + Quando eu preencho o campo "Nova Senha" com "SenhaForte@123" + E eu preencho o campo "Confirmar Senha" com "SenhaForte@123" + E eu clico no botão "Definir Senha" + Então eu devo ser redirecionado para a página de "Login" + E eu devo ver a mensagem "Senha definida com sucesso! Você já pode fazer o login." + +Cenário: Usuário tenta definir senhas que não são idênticas (Caminho Triste) + Dado que eu acessei a página "Definir Senha" através de um link de cadastro válido + Quando eu preencho o campo "Nova Senha" com "SenhaForte@123" + E eu preencho o campo "Confirmar Senha" com "SenhaDiferente@123" + E eu clico no botão "Definir Senha" + Então eu devo continuar na página "Definir Senha" + E eu devo ver a mensagem de erro "As senhas não conferem." + +Cenário: Usuário tenta definir uma senha muito curta (Caminho Triste) + Dado que eu acessei a página "Definir Senha" através de um link de cadastro válido + Quando eu preencho o campo "Nova Senha" com "123" + E eu preencho o campo "Confirmar Senha" com "123" + E eu clico no botão "Definir Senha" + Então eu devo continuar na página "Definir Senha" + E eu devo ver a mensagem de erro "A senha deve ter no mínimo 8 caracteres." + +Cenário: Usuário tenta definir uma senha fraca (Caminho Triste) + Dado que eu acessei a página "Definir Senha" através de um link de cadastro válido + Quando eu preencho o campo "Nova Senha" com "SenhaFraca" + E eu preencho o campo "Confirmar Senha" com "SenhaFraca" + E eu clico no botão "Definir Senha" + Então eu devo continuar na página "Definir Senha" + E eu devo ver a mensagem de erro "Não atende aos requisitos mínimos: mínimo 8 caracteres, sendo obrigatório 1 caractere especial, 1 número, 1 letra maiúscula e 1 letra minúscula!" From 939c5ec8450bc996330145c6b0d29a1eeaacebd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Mon, 17 Nov 2025 11:37:46 -0300 Subject: [PATCH 08/42] =?UTF-8?q?Add=20login=20feature=20scenarios=20para?= =?UTF-8?q?=20usu=C3=A1rios=20autenticados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/login/sistema_login.feature | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 features/login/sistema_login.feature diff --git a/features/login/sistema_login.feature b/features/login/sistema_login.feature new file mode 100644 index 0000000000..2cc137728d --- /dev/null +++ b/features/login/sistema_login.feature @@ -0,0 +1,40 @@ +Funcionalidade: Autenticação de usuário no sistema + Como um Usuário do sistema + Eu quero acessar o sistema utilizando um e-mail ou matrícula e uma senha já cadastrada + A fim de responder formulários ou gerenciar o sistema + +Cenário: Administrador faz login com sucesso (Caminho Feliz) + Dado que eu estou na página de "Login" + E existe um usuário "usuario_valido@alias" com a senha "senha123" e perfil "Admin" + Quando eu preencho "E-mail ou Matrícula" com "usuario_valido@alias" ou "Matricula" + E preencho "Senha" com "senha123" + E clico em "Entrar" + Então eu devo ser redirecionado para a página "Dashboard Admin" + E eu devo ver o link "Gerenciamento" no menu lateral + +Cenário: Aluno (usuário comum) faz login com sucesso (Caminho Feliz) + Dado que eu estou na página de "Login" + E existe um usuário "usuario_valido@alias" com a senha "senha456" e perfil "Aluno" + Quando eu preencho "E-mail ou Matrícula" com "usuario_valido@alias" ou "Matricula" + E preencho "Senha" com "senha456" + E clico em "Entrar" + Então eu devo ser redirecionado para a página "Dashboard Aluno" + E eu não devo ver o link "Gerenciamento" no menu lateral + +Cenário: Professor (usuário comum) faz login com sucesso (Caminho Feliz) + Dado que eu estou na página de "Login" + E existe um usuário "usuario_valido@alias" com a senha "senha456" e perfil "Aluno" + Quando eu preencho "E-mail ou Matrícula" com "usuario_valido@alias" ou "Matricula" + E preencho "Senha" com "senha456" + E clico em "Entrar" + Então eu devo ser redirecionado para a página "Dashboard Professor" + E eu não devo ver o link "Gerenciamento" no menu lateral + +Cenário: Usuário tenta fazer login com senha incorreta (Caminho Triste) + Dado que eu estou na página de "Login" + E existe um usuário "usuario_valido@alias" com a senha "senha456" + Quando eu preencho "E-mail ou Matrícula" com "usuario_valido@alias" ou "Matricula" + E preencho "Senha" com "senhaErrada" + E clico em "Entrar" + Então eu devo continuar na página de "Login" + E eu devo ver a mensagem de erro "E-mail ou senha inválidos." From 3b8f7954f0994c0a00eaa11a30cb63584be79313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Mon, 17 Nov 2025 11:47:53 -0300 Subject: [PATCH 09/42] =?UTF-8?q?Add=20feature=20para=20registro=20de=20us?= =?UTF-8?q?u=C3=A1rios=20via=20importa=C3=A7=C3=A3o=20JSON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/cadastro/cadastrar_usuarios.feature | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 features/cadastro/cadastrar_usuarios.feature diff --git a/features/cadastro/cadastrar_usuarios.feature b/features/cadastro/cadastrar_usuarios.feature new file mode 100644 index 0000000000..05645330a7 --- /dev/null +++ b/features/cadastro/cadastrar_usuarios.feature @@ -0,0 +1,35 @@ +Funcionalidade: Cadastro de usuários do SIGAA via importação de dados + Como um Administrador + Eu quero cadastrar participantes de turmas do SIGAA ao importar dados de usuarios novos + A fim de que eles acessem o sistema CAMAAR + +Cenário: Admin importa JSON com um novo aluno (Caminho Feliz) + Dado que eu estou logado como "admin_valido@alias" + E eu estou na página que contém o botão "Importar dados" + E o banco de dados não contém o aluno "Novo Aluno" (matrícula "200012345") + E eu tenho um arquivo "turmas_novo_aluno.json" que contém "Novo Aluno" (200012345) com o email "novo.aluno@alias" + Quando eu seleciono o arquivo "turmas_novo_aluno.json" + E importo-o ao sistema + Então eu devo ver a mensagem "Importação concluída." + E o aluno "Novo Aluno" (200012345) deve existir no sistema com status "Pendente" + E um e-mail de definição de senha deve ser enviado para "novo.aluno@alias" + +Cenário: Admin importa JSON com um novo professor (Caminho Feliz) + Dado que eu estou logado como "admin_valido@alias" + E eu estou na página que contém o botão "Importar dados" + E o banco de dados não contém o professor "Novo Professor" (matrícula "XXXXXXXXX") + E eu tenho um arquivo "departamento_novo_professor.json" que contém "Novo Professor" (XXXXXXXXX) com o email "novo.professor@alias" + Quando eu seleciono o arquivo "departamento_novo_professor.json" + E importo-o ao sistema + Então eu devo ver a mensagem "Importação concluída." + E o professor "Novo Professor" (XXXXXXXXX) deve existir no sistema com status "Pendente" + E um e-mail de definição de senha deve ser enviado para "novo.professor@alias" + +Cenário: Admin importa JSON de turma com aluno novo sem a chave "email" (Caminho Triste) + Dado que eu estou logado como "admin_valido@alias" + E eu estou na página que contém o botão "Importar dados" + E eu tenho um arquivo "turmas_sem_email.json" onde um "discente" novo não possui a chave "email" + Quando eu seleciono o arquivo "turmas_sem_email.json" + E importo-o ao sistema + Então eu devo ver a mensagem de erro "Erro na importação: O arquivo JSON é inválido." + E nenhum novo usuário deve ser criado From cee2de9f04726338f74bf532c288267490ac06de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:35:57 -0300 Subject: [PATCH 10/42] Create bdd_templates.feature --- .../bdd_templates.feature | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 features/ template_formularios /bdd_templates.feature diff --git a/features/ template_formularios /bdd_templates.feature b/features/ template_formularios /bdd_templates.feature new file mode 100644 index 0000000000..54d0a1425a --- /dev/null +++ b/features/ template_formularios /bdd_templates.feature @@ -0,0 +1,86 @@ +Funcionalidade: Criar template de formulário + +Cenário: Criação de template com dados válidos (Feliz) + Dado que estou na página de criação de templates + E preencho o campo "Nome do template" com "Avaliação 2024" + E adiciono um tipo de questão de múltipla escolha + E adiciono um tipo de questão discursiva + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem "Template criado com sucesso" + E o template deve ser salvo no banco de dados + +Cenário: Tentativa de criação com título vazio (Triste) + Dado que estou na página de criação de templates + E deixo o campo "Título" vazio + E adiciono tipos de questões válidas + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" + E o template não deve ser salvo + +Cenário: Tentativa de criação sem questões (Triste) + Dado que preencho o título corretamente + E não adiciono nenhum tipo de questão ao template + Quando clico no botão "Salvar Template" + Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" + E o template não deve ser salvo + + +Funcionalidade: Visualização dos templates criados + +Cenário: Visualizar lista de templates existentes (Feliz) + Dado que existem templates salvos no sistema + Quando eu acesso a página "Templates" + Então devo ver uma lista contendo todos os templates criados + E devo ver as opções de "Editar" e "Deletar" para cada template da lista + +Cenário: Visualizar lista vazia (Triste) + Dado que não existe nenhum template salvo no sistema + Quando eu acesso a página "Templates" + Então o sistema deve exibir a mensagem "Nenhum template foi criado" + E a lista de visualização deve estar vazia + + Funcionalidade: Edição e Deleção de Templates + +Cenário: Edição de nome de template usado em formulário antigo (Feliz) + Dado que tenho o template "Avaliação A" associado a um formulário já respondido + Quando eu edito o nome do template para "Avaliação A - Revisada" + E clico no botão "Salvar" + Então o sistema deve atualizar o template para "Avaliação A - Revisada" + E os formulários antigos criados com o template "Avaliação A" não devem sofrer alteração + +Cenário: Deleção de um template existente (Feliz) + Dado que seleciono um template existente na lista + Quando clico em "Deletar" + E aparece um pop-up com o texto "Você tem certeza que deseja deletar este template?" + E confirmo a ação clicando no botão "Confirmar" + Então o template deve ser removido da lista de visualização + E não devo ver ele no gerenciamento de templates + +Cenário: Edição com caracteres inválidos no título (Triste) + Dado que estou na tela de edição de um template + Quando preencho o campo "Título" com caracteres não permitidos + Então o sistema deve exibir a mensagem "Formato de título inválido" + E aparece uma mensagem de texto indicando quais caracteres não são permitidos + E as alterações não devem ser salvas + + Funcionalidade: Criação de formulário para docentes ou dicentes + +Cenário: Enviar formulário para Discentes de uma turma específica (Feliz) + Dado que estou criando um novo formulário a partir de um template + Quando seleciono a opção "Discentes" no campo de público-alvo + E seleciono uma turma válida "Turma A - Engenharia" + E clico no botão "Enviar" + Então o formulário deve ser enviado especificamente para os alunos daquela turma + +Cenário: Enviar formulário para Docentes (Feliz) + Dado que estou criando um novo formulário + Quando seleciono a opção "Docentes" no campo de público-alvo + Então o formulário deve ser enviado especificamente para os professores + E o campo de seleção de turma deve ficar oculto ou opcional + +Cenário: Tentativa de criar sem selecionar público (Triste) + Dado que preenchi os dados básicos do formulário + E não selecionei nem "Docente" nem "Discente" + Quando tento clicar em "Enviar" + Então o sistema deve exibir o erro "Selecione o público-alvo da avaliação" + E não deve enviar o formulário From df0e23eae83f92f16ad61875639ace90008c6071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:38:15 -0300 Subject: [PATCH 11/42] Update bdd_templates.feature Especificando BDD dos templates --- features/ template_formularios /bdd_templates.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/ template_formularios /bdd_templates.feature b/features/ template_formularios /bdd_templates.feature index 54d0a1425a..9de823804f 100644 --- a/features/ template_formularios /bdd_templates.feature +++ b/features/ template_formularios /bdd_templates.feature @@ -1,4 +1,4 @@ -Funcionalidade: Criar template de formulário +Funcionalidade: Criar template de formulário Cenário: Criação de template com dados válidos (Feliz) Dado que estou na página de criação de templates From f27da391f766bc525cd046d20ec219ad8ed3ff92 Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Mon, 17 Nov 2025 19:38:40 -0300 Subject: [PATCH 12/42] gerenciamento forms --- .dockerignore | 85 ++++++++----------- README.Docker.md | 17 ++++ docker-compose.yml | 58 +++++++++++-- .../criar_formulario.feature | 30 +++++++ .../responder_formulario.feature | 36 ++++++++ .../visualizar_formulario.feature | 19 +++++ .../visualizar_resposta_formulario.feature | 17 ++++ 7 files changed, 203 insertions(+), 59 deletions(-) create mode 100644 README.Docker.md create mode 100644 features/step_definitions/Gerenciamento_forms/criar_formulario.feature create mode 100644 features/step_definitions/Gerenciamento_forms/responder_formulario.feature create mode 100644 features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature create mode 100644 features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature diff --git a/.dockerignore b/.dockerignore index 325bfc036d..03a268b8ba 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,51 +1,34 @@ -# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. - -# Ignore git directory. -/.git/ -/.gitignore - -# Ignore bundler config. -/.bundle - -# Ignore all environment files. -/.env* - -# Ignore all default key files. -/config/master.key -/config/credentials/*.key - -# Ignore all logfiles and tempfiles. -/log/* -/tmp/* -!/log/.keep -!/tmp/.keep - -# Ignore pidfiles, but keep the directory. -/tmp/pids/* -!/tmp/pids/.keep - -# Ignore storage (uploaded files in development and any SQLite databases). -/storage/* -!/storage/.keep -/tmp/storage/* -!/tmp/storage/.keep - -# Ignore assets. -/node_modules/ -/app/assets/builds/* -!/app/assets/builds/.keep -/public/assets - -# Ignore CI service files. -/.github - -# Ignore Kamal files. -/config/deploy*.yml -/.kamal - -# Ignore development files -/.devcontainer - -# Ignore Docker-related files -/.dockerignore -/Dockerfile* +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose.y*ml +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/README.Docker.md b/README.Docker.md new file mode 100644 index 0000000000..ffca340863 --- /dev/null +++ b/README.Docker.md @@ -0,0 +1,17 @@ +### Building and running your application + +When you're ready, start your application by running: +`docker compose up --build`. + +### Deploying your application to the cloud + +First, build your image, e.g.: `docker build -t myapp .`. +If your cloud uses a different CPU architecture than your development +machine (e.g., you are on a Mac M1 and your cloud provider is amd64), +you'll want to build the image for that platform, e.g.: +`docker build --platform=linux/amd64 -t myapp .`. + +Then, push it to your registry, e.g. `docker push myregistry.com/myapp`. + +Consult Docker's [getting started](https://docs.docker.com/go/get-started-sharing/) +docs for more detail on building and pushing. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index da38d35673..6a19e9a592 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,52 @@ -version: "3.9" +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Docker Compose reference guide at +# https://docs.docker.com/go/compose-spec-reference/ +# Here the instructions define your application as a service called "app". +# This service is built from the Dockerfile in the current directory. +# You can add other services your application may depend on here, such as a +# database or a cache. For examples, see the Awesome Compose repository: +# https://github.com/docker/awesome-compose services: - web: - build: . - command: ./bin/dev - volumes: - - .:/rails - ports: - - "3000:3000" + app: + build: + context: . + target: final + # If your application exposes a port, uncomment the following lines and change + # the port numbers as needed. The first number is the host port and the second + # is the port inside the container. + # ports: + # - 8080:8080 + + # The commented out section below is an example of how to define a PostgreSQL + # database that your application can use. `depends_on` tells Docker Compose to + # start the database before your application. The `db-data` volume persists the + # database data between container restarts. The `db-password` secret is used + # to set the database password. You must create `db/password.txt` and add + # a password of your choosing to it before running `docker compose up`. + # depends_on: + # db: + # condition: service_healthy + # db: + # image: postgres + # restart: always + # user: postgres + # secrets: + # - db-password + # volumes: + # - db-data:/var/lib/postgresql/data + # environment: + # - POSTGRES_DB=example + # - POSTGRES_PASSWORD_FILE=/run/secrets/db-password + # expose: + # - 5432 + # healthcheck: + # test: [ "CMD", "pg_isready" ] + # interval: 10s + # timeout: 5s + # retries: 5 + # volumes: + # db-data: + # secrets: + # db-password: + # file: db/password.txt diff --git a/features/step_definitions/Gerenciamento_forms/criar_formulario.feature b/features/step_definitions/Gerenciamento_forms/criar_formulario.feature new file mode 100644 index 0000000000..ca024eb585 --- /dev/null +++ b/features/step_definitions/Gerenciamento_forms/criar_formulario.feature @@ -0,0 +1,30 @@ + Funcionalidade: Criar formulário de avaliação + Eu como Administrador + Quero criar um formulário baseado em um template para as turmas que eu escolher + A fim de avaliar o desempenho das turmas no semestre atual + + Cenário: Criar formulário de avaliação para turmas selecionadas + Dado que eu estou logado como Administrador + E que eu tenho acesso ao template de formulário "Avaliação Semestral" + Quando eu seleciono as turmas "Turma A", "Turma B" e "Turma C" + E eu escolho o template "Avaliação Semestral" + E eu clico em "Criar Formulário" + Então o sistema deve criar formulários de avaliação para as turmas selecionadas + E eu devo ver uma mensagem de sucesso "Formulários criados com sucesso para as turmas selecionadas." + + Cenário: Tentativa de criação sem selecionar turmas + Dado que eu estou logado como Administrador + E que existe um template de formulário chamado "Avaliação Semestral" + Quando eu escolho o template "Avaliação Semestral" + E eu clico em "Criar Formulário" + Então eu devo ver uma mensagem de erro "Nenhuma turma selecionada." + E nenhum formulário deve ser criado + + Cenário: Tentativa de criação sem selecionar template + Dado que eu estou logado como Administrador + E que existem turmas cadastradas no sistema + Quando eu seleciono as turmas "Turma A" e "Turma B" + E eu clico em "Criar Formulário" + Então eu devo ver uma mensagem de erro "Nenhum template selecionado." + E nenhum formulário deve ser criado + diff --git a/features/step_definitions/Gerenciamento_forms/responder_formulario.feature b/features/step_definitions/Gerenciamento_forms/responder_formulario.feature new file mode 100644 index 0000000000..c4cfbe21a6 --- /dev/null +++ b/features/step_definitions/Gerenciamento_forms/responder_formulario.feature @@ -0,0 +1,36 @@ + Funcionalidade: Responder formulário + Eu como Participante de uma turma + Quero responder o questionário sobre a turma em que estou matriculado + A fim de submeter minha avaliação da turma + + Cenário: Responder formulário de avaliação para uma turma + Dado que eu estou logado como Participante + E que eu estou matriculado na turma "Turma A" + E que existe um formulário de avaliação disponível para "Turma A" + Quando eu acesso o formulário de avaliação para "Turma A" + E eu preencho o formulário com as respostas necessárias + E eu clico em "Enviar Formulário" + Então o sistema deve registrar minhas respostas para o formulário de "Turma A" + E eu devo ver uma mensagem de confirmação "Seu formulário foi enviado com sucesso." + + Cenário: Tentativa de enviar formulário sem preencher campos obrigatórios + Dado que eu estou logado como Participante + E que existe um formulário de avaliação ativo para "Turma A" + Quando eu acesso o formulário de avaliação de "Turma A" + E eu envio o formulário sem preencher os campos obrigatórios + Então eu devo ver uma mensagem de erro indicando os campos faltantes + E as respostas não devem ser registradas + + Cenário: Tentativa de enviar formulário sem preencher campos obrigatórios + Dado que eu estou logado como Participante + E que existe um formulário de avaliação ativo para "Turma A" + Quando eu acesso o formulário de avaliação de "Turma A" + E eu envio o formulário sem preencher os campos obrigatórios + Então eu devo ver uma mensagem de erro indicando os campos faltantes + E as respostas não devem ser registradas + + + + + + diff --git a/features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature b/features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature new file mode 100644 index 0000000000..97da17fed1 --- /dev/null +++ b/features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature @@ -0,0 +1,19 @@ +Funcionalidade: Visualização de formulários para responder + Eu como Participante de uma turma + Quero visualizar os formulários não respondidos das turmas em que estou matriculado + A fim de poder escolher qual irei responder + + Cenário: Visualizar formulários não respondidos para turmas matriculadas + Dado que eu estou logado como Participante + E que eu estou matriculado nas turmas "Turma A" e "Turma B" + E que existem formulários não respondidos para essas turmas + Quando eu acesso a seção de formulários disponíveis + Então eu devo ver os formulários não respondidos para "Turma A" e "Turma B" + E eu devo ver uma mensagem indicando o número de formulários pendentes "Você tem 2 formulários para responder." + + Cenário: Nenhum formulário pendente + Dado que eu estou logado como Participante + E que eu estou matriculado nas turmas "Turma A" e "Turma B" + E que não existem formulários pendentes + Quando eu acesso a seção "Formulários Disponíveis" + Então eu devo ver a mensagem "Você não possui formulários pendentes." diff --git a/features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature b/features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature new file mode 100644 index 0000000000..1793ae6cf5 --- /dev/null +++ b/features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature @@ -0,0 +1,17 @@ + Funcionalidade: Visualização de resultados dos formulários + Eu como Administrador + Quero visualizar os formulários criados + A fim de poder gerar um relatório a partir das respostas + + Cenário: Visualizar formulários criados para turmas selecionadas + Dado que eu estou logado como Administrador + E que eu tenho formulários criados para as turmas "Turma A" e "Turma B" + Quando eu acesso a seção de formulários criados + Então eu devo ver os formulários criados para "Turma A" e "Turma B" + E eu devo ver uma mensagem indicando o número de formulários criados "Existem 2 formulários criados." s + + Cenário: Visualizar detalhes de um formulários + Dado que eu estou logado como Administrador + E que existe um formulário criado para a turma "Turma A" + Quando eu seleciono o formulário de "Turma A" na lista + Então eu devo visualizar as perguntas, respostas e estatísticas do formulário From f4b7c1e71b8aef24aee4e1ced0fa8a58502c9c5a Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Mon, 17 Nov 2025 19:46:07 -0300 Subject: [PATCH 13/42] Fix(local) ajuste de local BDD formularios --- .../Gerenciamento_forms/criar_formulario.feature | 0 .../Gerenciamento_forms/responder_formulario.feature | 0 .../Gerenciamento_forms/visualizar_formulario.feature | 0 .../Gerenciamento_forms/visualizar_resposta_formulario.feature | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename features/{step_definitions => }/Gerenciamento_forms/criar_formulario.feature (100%) rename features/{step_definitions => }/Gerenciamento_forms/responder_formulario.feature (100%) rename features/{step_definitions => }/Gerenciamento_forms/visualizar_formulario.feature (100%) rename features/{step_definitions => }/Gerenciamento_forms/visualizar_resposta_formulario.feature (100%) diff --git a/features/step_definitions/Gerenciamento_forms/criar_formulario.feature b/features/Gerenciamento_forms/criar_formulario.feature similarity index 100% rename from features/step_definitions/Gerenciamento_forms/criar_formulario.feature rename to features/Gerenciamento_forms/criar_formulario.feature diff --git a/features/step_definitions/Gerenciamento_forms/responder_formulario.feature b/features/Gerenciamento_forms/responder_formulario.feature similarity index 100% rename from features/step_definitions/Gerenciamento_forms/responder_formulario.feature rename to features/Gerenciamento_forms/responder_formulario.feature diff --git a/features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature b/features/Gerenciamento_forms/visualizar_formulario.feature similarity index 100% rename from features/step_definitions/Gerenciamento_forms/visualizar_formulario.feature rename to features/Gerenciamento_forms/visualizar_formulario.feature diff --git a/features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature b/features/Gerenciamento_forms/visualizar_resposta_formulario.feature similarity index 100% rename from features/step_definitions/Gerenciamento_forms/visualizar_resposta_formulario.feature rename to features/Gerenciamento_forms/visualizar_resposta_formulario.feature From cc49383bfcf45bf1909dbdb14d46116ef4ebc243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:57:12 -0300 Subject: [PATCH 14/42] Create criar_template.feature --- .../criar_template.feature | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 features/ template_formularios /criar_template.feature diff --git a/features/ template_formularios /criar_template.feature b/features/ template_formularios /criar_template.feature new file mode 100644 index 0000000000..dac7934038 --- /dev/null +++ b/features/ template_formularios /criar_template.feature @@ -0,0 +1,25 @@ +Funcionalidade: Criar template de formulário + +Cenário: Criação de template com dados válidos (Feliz) + Dado que estou na página de criação de templates + E preencho o campo "Nome do template" com "Avaliação 2024" + E adiciono um tipo de questão de múltipla escolha + E adiciono um tipo de questão discursiva + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem "Template criado com sucesso" + E o template deve ser salvo no banco de dados + +Cenário: Tentativa de criação com título vazio (Triste) + Dado que estou na página de criação de templates + E deixo o campo "Título" vazio + E adiciono tipos de questões válidas + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" + E o template não deve ser salvo + +Cenário: Tentativa de criação sem questões (Triste) + Dado que preencho o título corretamente + E não adiciono nenhum tipo de questão ao template + Quando clico no botão "Salvar Template" + Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" + E o template não deve ser salvo From e2604402c37b3e25c717ade0b1c7dab03ad9d741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:57:51 -0300 Subject: [PATCH 15/42] Add files via upload --- .../criar_template.feature | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 features/ template_formularios/criar_template.feature diff --git a/features/ template_formularios/criar_template.feature b/features/ template_formularios/criar_template.feature new file mode 100644 index 0000000000..dac7934038 --- /dev/null +++ b/features/ template_formularios/criar_template.feature @@ -0,0 +1,25 @@ +Funcionalidade: Criar template de formulário + +Cenário: Criação de template com dados válidos (Feliz) + Dado que estou na página de criação de templates + E preencho o campo "Nome do template" com "Avaliação 2024" + E adiciono um tipo de questão de múltipla escolha + E adiciono um tipo de questão discursiva + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem "Template criado com sucesso" + E o template deve ser salvo no banco de dados + +Cenário: Tentativa de criação com título vazio (Triste) + Dado que estou na página de criação de templates + E deixo o campo "Título" vazio + E adiciono tipos de questões válidas + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" + E o template não deve ser salvo + +Cenário: Tentativa de criação sem questões (Triste) + Dado que preencho o título corretamente + E não adiciono nenhum tipo de questão ao template + Quando clico no botão "Salvar Template" + Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" + E o template não deve ser salvo From 59acddccf382a22a174e1da03bcdf52b33157528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:58:49 -0300 Subject: [PATCH 16/42] Create criar_template.feature --- .../criar_template.feature | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 features/ template_formularios /criar_template.feature diff --git a/features/ template_formularios /criar_template.feature b/features/ template_formularios /criar_template.feature new file mode 100644 index 0000000000..dac7934038 --- /dev/null +++ b/features/ template_formularios /criar_template.feature @@ -0,0 +1,25 @@ +Funcionalidade: Criar template de formulário + +Cenário: Criação de template com dados válidos (Feliz) + Dado que estou na página de criação de templates + E preencho o campo "Nome do template" com "Avaliação 2024" + E adiciono um tipo de questão de múltipla escolha + E adiciono um tipo de questão discursiva + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem "Template criado com sucesso" + E o template deve ser salvo no banco de dados + +Cenário: Tentativa de criação com título vazio (Triste) + Dado que estou na página de criação de templates + E deixo o campo "Título" vazio + E adiciono tipos de questões válidas + Quando clico no botão "Salvar Template" + Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" + E o template não deve ser salvo + +Cenário: Tentativa de criação sem questões (Triste) + Dado que preencho o título corretamente + E não adiciono nenhum tipo de questão ao template + Quando clico no botão "Salvar Template" + Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" + E o template não deve ser salvo From 0b2f6f204a527db3378a62b89d20b5c4ca7754fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:59:31 -0300 Subject: [PATCH 17/42] Create visualizar_template.feature --- .../visualizar_template.feature | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 features/ template_formularios /visualizar_template.feature diff --git a/features/ template_formularios /visualizar_template.feature b/features/ template_formularios /visualizar_template.feature new file mode 100644 index 0000000000..e878d2ace3 --- /dev/null +++ b/features/ template_formularios /visualizar_template.feature @@ -0,0 +1,37 @@ +Funcionalidade: Visualização dos templates criados + +Cenário: Visualizar lista de templates existentes (Feliz) + Dado que existem templates salvos no sistema + Quando eu acesso a página "Templates" + Então devo ver uma lista contendo todos os templates criados + E devo ver as opções de "Editar" e "Deletar" para cada template da lista + +Cenário: Visualizar lista vazia (Triste) + Dado que não existe nenhum template salvo no sistema + Quando eu acesso a página "Templates" + Então o sistema deve exibir a mensagem "Nenhum template foi criado" + E a lista de visualização deve estar vazia + + Funcionalidade: Edição e Deleção de Templates + +Cenário: Edição de nome de template usado em formulário antigo (Feliz) + Dado que tenho o template "Avaliação A" associado a um formulário já respondido + Quando eu edito o nome do template para "Avaliação A - Revisada" + E clico no botão "Salvar" + Então o sistema deve atualizar o template para "Avaliação A - Revisada" + E os formulários antigos criados com o template "Avaliação A" não devem sofrer alteração + +Cenário: Deleção de um template existente (Feliz) + Dado que seleciono um template existente na lista + Quando clico em "Deletar" + E aparece um pop-up com o texto "Você tem certeza que deseja deletar este template?" + E confirmo a ação clicando no botão "Confirmar" + Então o template deve ser removido da lista de visualização + E não devo ver ele no gerenciamento de templates + +Cenário: Edição com caracteres inválidos no título (Triste) + Dado que estou na tela de edição de um template + Quando preencho o campo "Título" com caracteres não permitidos + Então o sistema deve exibir a mensagem "Formato de título inválido" + E aparece uma mensagem de texto indicando quais caracteres não são permitidos + E as alterações não devem ser salvas From eed4c8375aa40efa6e7886fc24da4606044c6bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:00:11 -0300 Subject: [PATCH 18/42] Create criar_formulario.feature --- .../criar_formulario.feature | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 features/ template_formularios /criar_formulario.feature diff --git a/features/ template_formularios /criar_formulario.feature b/features/ template_formularios /criar_formulario.feature new file mode 100644 index 0000000000..0ba3dd1750 --- /dev/null +++ b/features/ template_formularios /criar_formulario.feature @@ -0,0 +1,21 @@ +Funcionalidade: Criação de formulário para docentes ou dicentes + +Cenário: Enviar formulário para Discentes de uma turma específica (Feliz) + Dado que estou criando um novo formulário a partir de um template + Quando seleciono a opção "Discentes" no campo de público-alvo + E seleciono uma turma válida "Turma A - Engenharia" + E clico no botão "Enviar" + Então o formulário deve ser enviado especificamente para os alunos daquela turma + +Cenário: Enviar formulário para Docentes (Feliz) + Dado que estou criando um novo formulário + Quando seleciono a opção "Docentes" no campo de público-alvo + Então o formulário deve ser enviado especificamente para os professores + E o campo de seleção de turma deve ficar oculto ou opcional + +Cenário: Tentativa de criar sem selecionar público (Triste) + Dado que preenchi os dados básicos do formulário + E não selecionei nem "Docente" nem "Discente" + Quando tento clicar em "Enviar" + Então o sistema deve exibir o erro "Selecione o público-alvo da avaliação" + E não deve enviar o formulário From 413c93aae9bc63bf8faa6578b9f9615e61479aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:00:42 -0300 Subject: [PATCH 19/42] Update visualizar_template.feature --- .../visualizar_template.feature | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/features/ template_formularios /visualizar_template.feature b/features/ template_formularios /visualizar_template.feature index e878d2ace3..439840ebc0 100644 --- a/features/ template_formularios /visualizar_template.feature +++ b/features/ template_formularios /visualizar_template.feature @@ -11,27 +11,3 @@ Cenário: Visualizar lista vazia (Triste) Quando eu acesso a página "Templates" Então o sistema deve exibir a mensagem "Nenhum template foi criado" E a lista de visualização deve estar vazia - - Funcionalidade: Edição e Deleção de Templates - -Cenário: Edição de nome de template usado em formulário antigo (Feliz) - Dado que tenho o template "Avaliação A" associado a um formulário já respondido - Quando eu edito o nome do template para "Avaliação A - Revisada" - E clico no botão "Salvar" - Então o sistema deve atualizar o template para "Avaliação A - Revisada" - E os formulários antigos criados com o template "Avaliação A" não devem sofrer alteração - -Cenário: Deleção de um template existente (Feliz) - Dado que seleciono um template existente na lista - Quando clico em "Deletar" - E aparece um pop-up com o texto "Você tem certeza que deseja deletar este template?" - E confirmo a ação clicando no botão "Confirmar" - Então o template deve ser removido da lista de visualização - E não devo ver ele no gerenciamento de templates - -Cenário: Edição com caracteres inválidos no título (Triste) - Dado que estou na tela de edição de um template - Quando preencho o campo "Título" com caracteres não permitidos - Então o sistema deve exibir a mensagem "Formato de título inválido" - E aparece uma mensagem de texto indicando quais caracteres não são permitidos - E as alterações não devem ser salvas From 655409bcc6408be9670994501022fcd29382857e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:01:07 -0300 Subject: [PATCH 20/42] Create editar_template.feature --- .../editar_template.feature | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 features/ template_formularios /editar_template.feature diff --git a/features/ template_formularios /editar_template.feature b/features/ template_formularios /editar_template.feature new file mode 100644 index 0000000000..76dd378cfb --- /dev/null +++ b/features/ template_formularios /editar_template.feature @@ -0,0 +1,23 @@ +Funcionalidade: Edição e Deleção de Templates + +Cenário: Edição de nome de template usado em formulário antigo (Feliz) + Dado que tenho o template "Avaliação A" associado a um formulário já respondido + Quando eu edito o nome do template para "Avaliação A - Revisada" + E clico no botão "Salvar" + Então o sistema deve atualizar o template para "Avaliação A - Revisada" + E os formulários antigos criados com o template "Avaliação A" não devem sofrer alteração + +Cenário: Deleção de um template existente (Feliz) + Dado que seleciono um template existente na lista + Quando clico em "Deletar" + E aparece um pop-up com o texto "Você tem certeza que deseja deletar este template?" + E confirmo a ação clicando no botão "Confirmar" + Então o template deve ser removido da lista de visualização + E não devo ver ele no gerenciamento de templates + +Cenário: Edição com caracteres inválidos no título (Triste) + Dado que estou na tela de edição de um template + Quando preencho o campo "Título" com caracteres não permitidos + Então o sistema deve exibir a mensagem "Formato de título inválido" + E aparece uma mensagem de texto indicando quais caracteres não são permitidos + E as alterações não devem ser salvas From 169c9368c6559eb25abd04c4de4716e3887b97c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:01:21 -0300 Subject: [PATCH 21/42] Delete features/ template_formularios /bdd_templates.feature --- .../bdd_templates.feature | 86 ------------------- 1 file changed, 86 deletions(-) delete mode 100644 features/ template_formularios /bdd_templates.feature diff --git a/features/ template_formularios /bdd_templates.feature b/features/ template_formularios /bdd_templates.feature deleted file mode 100644 index 9de823804f..0000000000 --- a/features/ template_formularios /bdd_templates.feature +++ /dev/null @@ -1,86 +0,0 @@ -Funcionalidade: Criar template de formulário - -Cenário: Criação de template com dados válidos (Feliz) - Dado que estou na página de criação de templates - E preencho o campo "Nome do template" com "Avaliação 2024" - E adiciono um tipo de questão de múltipla escolha - E adiciono um tipo de questão discursiva - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem "Template criado com sucesso" - E o template deve ser salvo no banco de dados - -Cenário: Tentativa de criação com título vazio (Triste) - Dado que estou na página de criação de templates - E deixo o campo "Título" vazio - E adiciono tipos de questões válidas - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" - E o template não deve ser salvo - -Cenário: Tentativa de criação sem questões (Triste) - Dado que preencho o título corretamente - E não adiciono nenhum tipo de questão ao template - Quando clico no botão "Salvar Template" - Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" - E o template não deve ser salvo - - -Funcionalidade: Visualização dos templates criados - -Cenário: Visualizar lista de templates existentes (Feliz) - Dado que existem templates salvos no sistema - Quando eu acesso a página "Templates" - Então devo ver uma lista contendo todos os templates criados - E devo ver as opções de "Editar" e "Deletar" para cada template da lista - -Cenário: Visualizar lista vazia (Triste) - Dado que não existe nenhum template salvo no sistema - Quando eu acesso a página "Templates" - Então o sistema deve exibir a mensagem "Nenhum template foi criado" - E a lista de visualização deve estar vazia - - Funcionalidade: Edição e Deleção de Templates - -Cenário: Edição de nome de template usado em formulário antigo (Feliz) - Dado que tenho o template "Avaliação A" associado a um formulário já respondido - Quando eu edito o nome do template para "Avaliação A - Revisada" - E clico no botão "Salvar" - Então o sistema deve atualizar o template para "Avaliação A - Revisada" - E os formulários antigos criados com o template "Avaliação A" não devem sofrer alteração - -Cenário: Deleção de um template existente (Feliz) - Dado que seleciono um template existente na lista - Quando clico em "Deletar" - E aparece um pop-up com o texto "Você tem certeza que deseja deletar este template?" - E confirmo a ação clicando no botão "Confirmar" - Então o template deve ser removido da lista de visualização - E não devo ver ele no gerenciamento de templates - -Cenário: Edição com caracteres inválidos no título (Triste) - Dado que estou na tela de edição de um template - Quando preencho o campo "Título" com caracteres não permitidos - Então o sistema deve exibir a mensagem "Formato de título inválido" - E aparece uma mensagem de texto indicando quais caracteres não são permitidos - E as alterações não devem ser salvas - - Funcionalidade: Criação de formulário para docentes ou dicentes - -Cenário: Enviar formulário para Discentes de uma turma específica (Feliz) - Dado que estou criando um novo formulário a partir de um template - Quando seleciono a opção "Discentes" no campo de público-alvo - E seleciono uma turma válida "Turma A - Engenharia" - E clico no botão "Enviar" - Então o formulário deve ser enviado especificamente para os alunos daquela turma - -Cenário: Enviar formulário para Docentes (Feliz) - Dado que estou criando um novo formulário - Quando seleciono a opção "Docentes" no campo de público-alvo - Então o formulário deve ser enviado especificamente para os professores - E o campo de seleção de turma deve ficar oculto ou opcional - -Cenário: Tentativa de criar sem selecionar público (Triste) - Dado que preenchi os dados básicos do formulário - E não selecionei nem "Docente" nem "Discente" - Quando tento clicar em "Enviar" - Então o sistema deve exibir o erro "Selecione o público-alvo da avaliação" - E não deve enviar o formulário From 009ef78e4f1779db356985ae3abfa0c457b45ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:01:34 -0300 Subject: [PATCH 22/42] Delete features/ template_formularios directory --- .../criar_template.feature | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 features/ template_formularios/criar_template.feature diff --git a/features/ template_formularios/criar_template.feature b/features/ template_formularios/criar_template.feature deleted file mode 100644 index dac7934038..0000000000 --- a/features/ template_formularios/criar_template.feature +++ /dev/null @@ -1,25 +0,0 @@ -Funcionalidade: Criar template de formulário - -Cenário: Criação de template com dados válidos (Feliz) - Dado que estou na página de criação de templates - E preencho o campo "Nome do template" com "Avaliação 2024" - E adiciono um tipo de questão de múltipla escolha - E adiciono um tipo de questão discursiva - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem "Template criado com sucesso" - E o template deve ser salvo no banco de dados - -Cenário: Tentativa de criação com título vazio (Triste) - Dado que estou na página de criação de templates - E deixo o campo "Título" vazio - E adiciono tipos de questões válidas - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" - E o template não deve ser salvo - -Cenário: Tentativa de criação sem questões (Triste) - Dado que preencho o título corretamente - E não adiciono nenhum tipo de questão ao template - Quando clico no botão "Salvar Template" - Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" - E o template não deve ser salvo From 8be98ee8bb2ce5a8624b272aa5b5c7c465fd7ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:01:47 -0300 Subject: [PATCH 23/42] Delete features/ template_formularios directory --- .../criar_template.feature | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 features/ template_formularios /criar_template.feature diff --git a/features/ template_formularios /criar_template.feature b/features/ template_formularios /criar_template.feature deleted file mode 100644 index dac7934038..0000000000 --- a/features/ template_formularios /criar_template.feature +++ /dev/null @@ -1,25 +0,0 @@ -Funcionalidade: Criar template de formulário - -Cenário: Criação de template com dados válidos (Feliz) - Dado que estou na página de criação de templates - E preencho o campo "Nome do template" com "Avaliação 2024" - E adiciono um tipo de questão de múltipla escolha - E adiciono um tipo de questão discursiva - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem "Template criado com sucesso" - E o template deve ser salvo no banco de dados - -Cenário: Tentativa de criação com título vazio (Triste) - Dado que estou na página de criação de templates - E deixo o campo "Título" vazio - E adiciono tipos de questões válidas - Quando clico no botão "Salvar Template" - Então o sistema deve exibir a mensagem de erro "O campo Título é obrigatório" - E o template não deve ser salvo - -Cenário: Tentativa de criação sem questões (Triste) - Dado que preencho o título corretamente - E não adiciono nenhum tipo de questão ao template - Quando clico no botão "Salvar Template" - Então o sistema deve exibir o erro "O template deve conter pelo menos uma questão" - E o template não deve ser salvo From 2a78174d790e0563c6acbfa241d44c2a039476f9 Mon Sep 17 00:00:00 2001 From: Carol <232050975@aluno.unb.br> Date: Mon, 17 Nov 2025 20:04:40 -0300 Subject: [PATCH 24/42] =?UTF-8?q?FEAT(add):=20adi=C3=A7=C3=A3o=20do=20BDD?= =?UTF-8?q?=20da=20issue=20#12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/gerenciamento_departamento.feature | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 features/admin/gerenciamento_departamento.feature diff --git a/features/admin/gerenciamento_departamento.feature b/features/admin/gerenciamento_departamento.feature new file mode 100644 index 0000000000..96c1b3bec6 --- /dev/null +++ b/features/admin/gerenciamento_departamento.feature @@ -0,0 +1,34 @@ +# language: pt-br + +Funcionalidade: Visualização de resultados de avaliação restrita por departamento + + Como um administrador + Eu quero gerenciar (ver e avaliar) somente as turmas do departamento ao qual eu pertenço + A fim de avaliar o desempenho das turmas no semestre atual + +Cenário: Admin do CIC vê apenas as turmas do CIC + Dado que eu estou logado como "admin@sistema.com" + E sou professor do depatamento "CIC" + E eu navego para a página "Gerenciamento" e clico em "Resultados" + E existe uma turma "Bancos de Dados (CIC0097)" que pertence ao departamento "CIC" + E existe uma turma "CÁLCULO 1 (MAT0025)" que pertence ao departamento "MAT" + Quando eu olho a lista de turmas na tela "Gerenciamento - Resultados" + Então eu devo ver o bloco da turma "Bancos de Dados (CIC0097)" + E eu não devo ver o bloco da turma "CÁLCULO 1 (MAT0025)" + +Cenário: Admin do MAT vê apenas as turmas do MAT + Dado que eu estou logado como "admin@sistema.com" + E sou professor do depatamento "MAT" + E eu navego para a página "Gerenciamento" e clico em "Resultados" + E existe uma turma "Bancos de Dados (CIC0097)" que pertence ao departamento "CIC" + E existe uma turma "CÁLCULO 1 (MAT0025)" que pertence ao departamento "MAT" + Quando eu olho a lista de turmas na tela "Gerenciamento - Resultados" + Então eu não devo ver o bloco da turma "Bancos de Dados (CIC0097)" + E eu devo ver o bloco da turma "CÁLCULO 1 (MAT0025)" + +Cenário: Admin do CIC tenta acessar resultados do MAT diretamente pela URL + Dado que eu estou logado como "admin@sistema.com" + E sou professor do depatamento "CIC" + E existe a turma "Cálculo 1 (MAT0025)" (de id: 42) que pertence ao departamento "MAT" + Quando eu tento acessar a URL "/gerenciamento/resultados/42" diretamente no meu navegador + Então eu devo ser redirecionado para a minha página inicial (ou "Dashboard") \ No newline at end of file From 8b3828f7a563e4df99102162988ac22b5f2167e9 Mon Sep 17 00:00:00 2001 From: mariosantos-05 Date: Mon, 17 Nov 2025 20:09:26 -0300 Subject: [PATCH 25/42] Update wiki --- Wiki.md | 179 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 84 deletions(-) diff --git a/Wiki.md b/Wiki.md index 1e009d7e9e..b4428fccf4 100644 --- a/Wiki.md +++ b/Wiki.md @@ -1,107 +1,118 @@ -# 📝 Wiki do Projeto – Sprint 1 +# 📝 Wiki do Projeto – Sprint 1 + **Grupo 1 – Engenharia de Software** -**Integrantes:** +**Integrantes:** -| Nome | Matrícula | -| :--- | :--- | -| Caroline | 232050975 | -| Célio | 211010350 | +| Nome | Matrícula | +| :---------- | :-------- | +| Caroline | 232050975 | +| Célio | 211010350 | | Luís Filipe | 190091975 | -| Mário | 231035778 | +| Mário | 231035778 | ---- +# 📌 Nome do Projeto -# 📌 Nome do Projeto -**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC Pipipipópópó(ainda a ser editado)** +**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC** ---- +# 📌 Escopo do Projeto -# 📌 Escopo do Projeto O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. -O projeto contempla funcionalidades de cadastro de usuários, criação de tarefas, acompanhamento de entregas e visualização de desempenho. - ---- +O projeto contempla funcionalidades de cadastro de usuários, redefinição de senha, importação de base de dados do SIGAA, visualização de formulários, criação de formulários, criação de templates para formulários e download de resultados dos relatórios. # 🔰 Papéis na Sprint 1 -## 🧑‍💼 Scrum Master -> **Função:** Responsável por garantir que a equipe siga a metodologia Scrum. Remove impedimentos que possam atrapalhar os desenvolvedores, facilita as cerimônias (Reuniões Diárias, Planejamento, Revisão e Retrospectiva) e protege o time de interrupções externas. -**Fulano** -### Funções: -- Facilitar as cerimônias da Sprint (Planning, Review, Retrospective). -- Remover impedimentos enfrentados pela equipe. -- Assegurar que o time siga os princípios ágeis. - ---- - -## 🧑‍💻 Product Owner -> **Função:** O "dono do produto". É a voz do cliente/usuário. Sua principal responsabilidade é definir *o que* será construído, criar e priorizar os itens do Product Backlog (as funcionalidades) para maximizar o valor entregue pela equipe a cada Sprint. - -**Fulana (00000000)** -### Funções: -- Definir e priorizar o Product Backlog. -- Garantir que as funcionalidades entreguem valor ao usuário final. -- Esclarecer dúvidas sobre requisitos. - ---- - -# 🚀 Funcionalidades da Sprint 1 - -A Sprint 1 tem como foco as **funcionalidades essenciais** relacionadas ao cadastro e acesso de usuários. - -## 📦 Funcionalidade 1 – Cadastro de Usuário -**Regra de Negócio:** -- O sistema deve validar e-mail único. -- Senha deve ter pelo menos 8 caracteres. -- O usuário só pode acessar o sistema após confirmar o e-mail. - -**Responsável:** Bombardilno crocodilo -**Histórias:** -- **US01**: “Como usuário, quero criar uma conta usando e-mail e senha para acessar o sistema.” - - **Story Points:** x -- **US02**: “Como usuário, quero receber um e-mail de confirmação para ativar minha conta.” - - **Story Points:** x - ---- - -## 📦 Funcionalidade 2 – Login no Sistema -**Regra de Negócio:** -- O sistema deve bloquear após 5 tentativas falhas consecutivas. -- O login só será autorizado caso o e-mail esteja verificado. - -**Responsável:** Bombardilno crocodilo -**Histórias:** -- **US03**: “Como usuário, quero fazer login com meu e-mail e senha para acessar o sistema.” - - **Story Points:** x -- **US04**: “Como usuário, quero recuperar minha senha caso eu a esqueça.” - - **Story Points:** x +● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o +Cucumber. +● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação +(BDD) no repositório principal. +● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a +matrícula dos integrantes. +● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo +as informações sobre a Sprint 1. + +## 🧑‍💼 Scrum Master + +Caroline, Célio, Luís Filipe e Mário. + +## 🧑‍💻 Product Owner + +Caroline, Célio, Luís Filipe e Mário. + +# Quais funcionalidades serão desenvolvidas? + +Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. +As US desta sprint são: +[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) +[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) +[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) +[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) +[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) +[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) +[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) +[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) +[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) +[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) +[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) +[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) +[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) +[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) +[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) +[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) + +# Quais serão as regras de negócio para cada funcionalidade? + +# Quem ficou responsável por cada cenário BDD em relação as US/Issues? + +#[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe +#[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe +#[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) Caroline +#[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) Mário +#[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) Célio +#[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) Caroline +#[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) Luís Filipe +#[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) Mário +#[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) Célio +#[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) Célio +#[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) (Caroline ou Luís Filipe) +#[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) Célio +#[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) Caroline +#[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) Mário +#[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) Mário +#[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) (Caroline ou Luís Filipe) --- # 📊 Métrica Velocity da Sprint 1 -| História | Pontos | -|----------|--------| -| US01 | X | -| US02 | X | -| US03 | X | -| US04 | X | -| **Total** | **x story points** | - -A *velocity* da Sprint 1 é **x pontos**. +| História/Issue | Pontos | +| ---------------- | ------------------- | +| US / #02 | 1 | +| US / #03 | 1 | +| US / #04 | 1 | +| US / #05 | 1 | +| US / #06 | 1 | +| US / #07 | 1 | +| US / #08 | 1 | +| US / #09 | 1 | +| US / #10 | 1 | +| US / #11 | 1 | +| US / #12 | 1 | +| US / #13 | 1 | +| US / #14 | 1 | +| US / #15 | 1 | +| US / #16 | 1 | +| US / #17 | 1 | +| **Total** | **Story Points** | +| **16 US/Issues** | **16 Story Points** | --- # 🌿 Política de Branching Utilizada pelo Grupo +Sprint Branching + Feature Branching (variação do GitLab Flow): ---- +- A equipe cria uma branch representando a sprint a partir da main. + +- Todas as feature branches da sprint nascem a partir dela. -# 📌 Resumo -Esta página da Wiki apresenta: -- Integrantes do grupo e papéis na Sprint -- Funcionalidades planejadas -- Regras de negócio -- Responsáveis -- Pontuação das histórias (Velocity) -- Política de branching adotada +- No final da sprint, tudo é consolidado e mergeado para a branch da sprint. From 1c530cb067bef88c8ef6fadd52583e6f39fee150 Mon Sep 17 00:00:00 2001 From: Mario Santos <76963308+mariosantos-05@users.noreply.github.com> Date: Mon, 17 Nov 2025 21:47:18 -0300 Subject: [PATCH 26/42] Update Wiki.md --- Wiki.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/Wiki.md b/Wiki.md index b4428fccf4..a6442192a8 100644 --- a/Wiki.md +++ b/Wiki.md @@ -60,8 +60,55 @@ As US desta sprint são: [17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) # Quais serão as regras de negócio para cada funcionalidade? - -# Quem ficou responsável por cada cenário BDD em relação as US/Issues? +## Regras de Negócio - Redefinição de Senha +(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-RS-01 | O usuário deve informar um e-mail cadastrado para solicitar a redefinição de senha. | +| RN-RS-02 | Caso o e-mail **não exista** no sistema, exibir mensagem de sucesso genérica ("Se este e-mail estiver cadastrado...") para evitar enumeração de usuários. | +| RN-RS-03 | Se o e-mail existir, gerar um **token único** de redefinição e enviá-lo por e-mail ao usuário. | +| RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | +| RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | +| RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | +## Regras de Negócio - Definição de Senha (Primeiro Acesso) +(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-DS-01 | O link de definição de senha é de **uso único**. | +| RN-DS-02 | A senha deve ter no mínimo **8 caracteres**, contendo letras maiúsculas, minúsculas e números. | +| RN-DS-03 | Os campos **"Nova Senha"** e **"Confirmar Senha"** devem ser idênticos; caso contrário, exibir erro. | +| RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | + +## Regras de Negócio - Cadastro de Usuários via Importação +(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-C-01 | A funcionalidade de importação só está acessível para usuários com perfil **"Admin"**. | +| RN-C-02 | Aceitar **apenas** arquivos no formato **.json**. Qualquer outro formato (ex: .pdf, .csv) → "Formato de arquivo inválido". | +| RN-C-03 | O arquivo deve ser um **JSON válido** (sintaxe correta). Erros de sintaxe → "O arquivo não é um JSON válido". | +| RN-C-04 | Cada objeto de usuário deve conter **obrigatoriamente** as chaves `"matricula"` e `"email"`. Falta de qualquer uma → rejeitar importação. | +| RN-C-05 | As chaves devem ter tipos corretos (ex: `"matricula"` deve ser número/string numérica válida). | +| RN-C-06 | Se a matrícula **não existir** no banco, criar novo usuário com status **"Pendente"**. | +| RN-C-07 | **Não** disparar automaticamente o e-mail de definição de senha ao criar usuário "Pendente" via importação. | +| RN-C-08 | Se a matrícula já existir, **não criar duplicata**. | +| RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | + +## Regras de Negócio - Sistema de Login +(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-L-01 | O usuário deve poder se autenticar usando **e-mail** ou **número de matrícula** no mesmo campo de login. | +| RN-L-02 | Os campos **"E-mail ou Matrícula"** e **"Senha"** são de preenchimento obrigatório. | +| RN-L-03 | Em caso de e-mail/matrícula ou senha incorretos, exibir mensagem genérica **"E-mail ou senha inválidos"** (nunca informar qual dos dois está errado). | +| RN-L-04 | Usuários com perfil **"Admin"** devem ter a opção **"Gerenciamento"** exibida no menu lateral. | +| RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | +| RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | + +## Quem ficou responsável por cada cenário BDD em relação as US/Issues? #[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe #[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe From bae9e4e522427c9d5c17df1bd813add5c3e18fa1 Mon Sep 17 00:00:00 2001 From: Mario Santos <76963308+mariosantos-05@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:54:18 -0300 Subject: [PATCH 27/42] Update wiki.md --- Wiki.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Wiki.md b/Wiki.md index a6442192a8..729449611a 100644 --- a/Wiki.md +++ b/Wiki.md @@ -108,6 +108,81 @@ As US desta sprint são: | RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | | RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | +## Regras de Negócio - Criar Formulário (Template de Questões) +(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | +| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | +## Regras de Negócio - Criar Template de Formulário +(Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | +| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | +## Regras de Negócio - Editar Template +(Issue 3: "Quero visualizar os templates criados") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | +| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | +## Regras de Negócio - Visualizar Templates +(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | +| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | + + + +## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) +(Issue 4: Importar dados do SIGAA) +(Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | +| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | +| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | +| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | + +## Regras de Negócio - Gerenciamento de Relatórios e Resultados +(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | +| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | +| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | + +## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) +(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | +| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | +| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | +| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | +| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | +| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | +| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | +| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | + +## Regras de Negócio - Gerenciamento de Turmas por Departamento +(Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | + + + + ## Quem ficou responsável por cada cenário BDD em relação as US/Issues? #[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe From 2b1269d5657649a6613c30bbabd4c2c49bea0e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:24:47 -0300 Subject: [PATCH 28/42] Rename Wiki.md to Wiki2.md trocando nome wiki --- Wiki.md => Wiki2.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Wiki.md => Wiki2.md (100%) diff --git a/Wiki.md b/Wiki2.md similarity index 100% rename from Wiki.md rename to Wiki2.md From 57d5031e03bbeb084f11d6fb8ddb48882c119ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:24:53 -0300 Subject: [PATCH 29/42] Update and rename README.md to Wiki.md --- README.md | 24 ------ Wiki.md | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 24 deletions(-) delete mode 100644 README.md create mode 100644 Wiki.md diff --git a/README.md b/README.md deleted file mode 100644 index 7db80e4ca1..0000000000 --- a/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... diff --git a/Wiki.md b/Wiki.md new file mode 100644 index 0000000000..729449611a --- /dev/null +++ b/Wiki.md @@ -0,0 +1,240 @@ +# 📝 Wiki do Projeto – Sprint 1 + +**Grupo 1 – Engenharia de Software** +**Integrantes:** + +| Nome | Matrícula | +| :---------- | :-------- | +| Caroline | 232050975 | +| Célio | 211010350 | +| Luís Filipe | 190091975 | +| Mário | 231035778 | + +# 📌 Nome do Projeto + +**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC** + +# 📌 Escopo do Projeto + +O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. +O projeto contempla funcionalidades de cadastro de usuários, redefinição de senha, importação de base de dados do SIGAA, visualização de formulários, criação de formulários, criação de templates para formulários e download de resultados dos relatórios. + +# 🔰 Papéis na Sprint 1 + +● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o +Cucumber. +● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação +(BDD) no repositório principal. +● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a +matrícula dos integrantes. +● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo +as informações sobre a Sprint 1. + +## 🧑‍💼 Scrum Master + +Caroline, Célio, Luís Filipe e Mário. + +## 🧑‍💻 Product Owner + +Caroline, Célio, Luís Filipe e Mário. + +# Quais funcionalidades serão desenvolvidas? + +Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. +As US desta sprint são: +[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) +[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) +[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) +[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) +[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) +[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) +[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) +[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) +[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) +[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) +[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) +[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) +[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) +[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) +[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) +[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) + +# Quais serão as regras de negócio para cada funcionalidade? +## Regras de Negócio - Redefinição de Senha +(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-RS-01 | O usuário deve informar um e-mail cadastrado para solicitar a redefinição de senha. | +| RN-RS-02 | Caso o e-mail **não exista** no sistema, exibir mensagem de sucesso genérica ("Se este e-mail estiver cadastrado...") para evitar enumeração de usuários. | +| RN-RS-03 | Se o e-mail existir, gerar um **token único** de redefinição e enviá-lo por e-mail ao usuário. | +| RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | +| RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | +| RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | +## Regras de Negócio - Definição de Senha (Primeiro Acesso) +(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-DS-01 | O link de definição de senha é de **uso único**. | +| RN-DS-02 | A senha deve ter no mínimo **8 caracteres**, contendo letras maiúsculas, minúsculas e números. | +| RN-DS-03 | Os campos **"Nova Senha"** e **"Confirmar Senha"** devem ser idênticos; caso contrário, exibir erro. | +| RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | + +## Regras de Negócio - Cadastro de Usuários via Importação +(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-C-01 | A funcionalidade de importação só está acessível para usuários com perfil **"Admin"**. | +| RN-C-02 | Aceitar **apenas** arquivos no formato **.json**. Qualquer outro formato (ex: .pdf, .csv) → "Formato de arquivo inválido". | +| RN-C-03 | O arquivo deve ser um **JSON válido** (sintaxe correta). Erros de sintaxe → "O arquivo não é um JSON válido". | +| RN-C-04 | Cada objeto de usuário deve conter **obrigatoriamente** as chaves `"matricula"` e `"email"`. Falta de qualquer uma → rejeitar importação. | +| RN-C-05 | As chaves devem ter tipos corretos (ex: `"matricula"` deve ser número/string numérica válida). | +| RN-C-06 | Se a matrícula **não existir** no banco, criar novo usuário com status **"Pendente"**. | +| RN-C-07 | **Não** disparar automaticamente o e-mail de definição de senha ao criar usuário "Pendente" via importação. | +| RN-C-08 | Se a matrícula já existir, **não criar duplicata**. | +| RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | + +## Regras de Negócio - Sistema de Login +(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-L-01 | O usuário deve poder se autenticar usando **e-mail** ou **número de matrícula** no mesmo campo de login. | +| RN-L-02 | Os campos **"E-mail ou Matrícula"** e **"Senha"** são de preenchimento obrigatório. | +| RN-L-03 | Em caso de e-mail/matrícula ou senha incorretos, exibir mensagem genérica **"E-mail ou senha inválidos"** (nunca informar qual dos dois está errado). | +| RN-L-04 | Usuários com perfil **"Admin"** devem ter a opção **"Gerenciamento"** exibida no menu lateral. | +| RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | +| RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | + +## Regras de Negócio - Criar Formulário (Template de Questões) +(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | +| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | +## Regras de Negócio - Criar Template de Formulário +(Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | +| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | +## Regras de Negócio - Editar Template +(Issue 3: "Quero visualizar os templates criados") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | +| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | +## Regras de Negócio - Visualizar Templates +(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | +| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | + + + +## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) +(Issue 4: Importar dados do SIGAA) +(Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | +| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | +| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | +| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | + +## Regras de Negócio - Gerenciamento de Relatórios e Resultados +(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | +| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | +| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | + +## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) +(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | +| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | +| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | +| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | +| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | +| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | +| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | +| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | + +## Regras de Negócio - Gerenciamento de Turmas por Departamento +(Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | + + + + +## Quem ficou responsável por cada cenário BDD em relação as US/Issues? + +#[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe +#[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe +#[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) Caroline +#[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) Mário +#[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) Célio +#[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) Caroline +#[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) Luís Filipe +#[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) Mário +#[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) Célio +#[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) Célio +#[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) (Caroline ou Luís Filipe) +#[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) Célio +#[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) Caroline +#[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) Mário +#[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) Mário +#[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) (Caroline ou Luís Filipe) + +--- + +# 📊 Métrica Velocity da Sprint 1 + +| História/Issue | Pontos | +| ---------------- | ------------------- | +| US / #02 | 1 | +| US / #03 | 1 | +| US / #04 | 1 | +| US / #05 | 1 | +| US / #06 | 1 | +| US / #07 | 1 | +| US / #08 | 1 | +| US / #09 | 1 | +| US / #10 | 1 | +| US / #11 | 1 | +| US / #12 | 1 | +| US / #13 | 1 | +| US / #14 | 1 | +| US / #15 | 1 | +| US / #16 | 1 | +| US / #17 | 1 | +| **Total** | **Story Points** | +| **16 US/Issues** | **16 Story Points** | + +--- + +# 🌿 Política de Branching Utilizada pelo Grupo + +Sprint Branching + Feature Branching (variação do GitLab Flow): + +- A equipe cria uma branch representando a sprint a partir da main. + +- Todas as feature branches da sprint nascem a partir dela. + +- No final da sprint, tudo é consolidado e mergeado para a branch da sprint. From e25e006c818c8a18a13557a584669df90d49ec45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:25:27 -0300 Subject: [PATCH 30/42] Create README.md --- README.md | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..5d99c9730e --- /dev/null +++ b/README.md @@ -0,0 +1,240 @@ +# 📝 Wiki do Projeto – Sprint 1: Etapa 1 + +**Grupo 1 – Engenharia de Software** +**Integrantes:** + +| Nome | Matrícula | +| :---------- | :-------- | +| Caroline | 232050975 | +| Célio | 211010350 | +| Luís Filipe | 190091975 | +| Mário | 231035778 | + +# 📌 Nome do Projeto + +**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC** + +# 📌 Escopo do Projeto + +O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. +O projeto contempla funcionalidades de cadastro de usuários, redefinição de senha, importação de base de dados do SIGAA, visualização de formulários, criação de formulários, criação de templates para formulários e download de resultados dos relatórios. + +# 🔰 Papéis na Sprint 1 + +● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o +Cucumber. +● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação +(BDD) no repositório principal. +● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a +matrícula dos integrantes. +● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo +as informações sobre a Sprint 1. + +## 🧑‍💼 Scrum Master + +Caroline, Célio, Luís Filipe e Mário. + +## 🧑‍💻 Product Owner + +Caroline, Célio, Luís Filipe e Mário. + +# Quais funcionalidades serão desenvolvidas? + +Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. +As US desta sprint são: +[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) +[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) +[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) +[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) +[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) +[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) +[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) +[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) +[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) +[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) +[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) +[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) +[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) +[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) +[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) +[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) + +# Quais serão as regras de negócio para cada funcionalidade? +## Regras de Negócio - Redefinição de Senha +(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-RS-01 | O usuário deve informar um e-mail cadastrado para solicitar a redefinição de senha. | +| RN-RS-02 | Caso o e-mail **não exista** no sistema, exibir mensagem de sucesso genérica ("Se este e-mail estiver cadastrado...") para evitar enumeração de usuários. | +| RN-RS-03 | Se o e-mail existir, gerar um **token único** de redefinição e enviá-lo por e-mail ao usuário. | +| RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | +| RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | +| RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | +## Regras de Negócio - Definição de Senha (Primeiro Acesso) +(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-DS-01 | O link de definição de senha é de **uso único**. | +| RN-DS-02 | A senha deve ter no mínimo **8 caracteres**, contendo letras maiúsculas, minúsculas e números. | +| RN-DS-03 | Os campos **"Nova Senha"** e **"Confirmar Senha"** devem ser idênticos; caso contrário, exibir erro. | +| RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | + +## Regras de Negócio - Cadastro de Usuários via Importação +(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-C-01 | A funcionalidade de importação só está acessível para usuários com perfil **"Admin"**. | +| RN-C-02 | Aceitar **apenas** arquivos no formato **.json**. Qualquer outro formato (ex: .pdf, .csv) → "Formato de arquivo inválido". | +| RN-C-03 | O arquivo deve ser um **JSON válido** (sintaxe correta). Erros de sintaxe → "O arquivo não é um JSON válido". | +| RN-C-04 | Cada objeto de usuário deve conter **obrigatoriamente** as chaves `"matricula"` e `"email"`. Falta de qualquer uma → rejeitar importação. | +| RN-C-05 | As chaves devem ter tipos corretos (ex: `"matricula"` deve ser número/string numérica válida). | +| RN-C-06 | Se a matrícula **não existir** no banco, criar novo usuário com status **"Pendente"**. | +| RN-C-07 | **Não** disparar automaticamente o e-mail de definição de senha ao criar usuário "Pendente" via importação. | +| RN-C-08 | Se a matrícula já existir, **não criar duplicata**. | +| RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | + +## Regras de Negócio - Sistema de Login +(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") + +| Código | Descrição | +|------------|---------------------------------------------------------------------------------------------------------------------| +| RN-L-01 | O usuário deve poder se autenticar usando **e-mail** ou **número de matrícula** no mesmo campo de login. | +| RN-L-02 | Os campos **"E-mail ou Matrícula"** e **"Senha"** são de preenchimento obrigatório. | +| RN-L-03 | Em caso de e-mail/matrícula ou senha incorretos, exibir mensagem genérica **"E-mail ou senha inválidos"** (nunca informar qual dos dois está errado). | +| RN-L-04 | Usuários com perfil **"Admin"** devem ter a opção **"Gerenciamento"** exibida no menu lateral. | +| RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | +| RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | + +## Regras de Negócio - Criar Formulário (Template de Questões) +(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | +| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | +## Regras de Negócio - Criar Template de Formulário +(Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | +| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | +## Regras de Negócio - Editar Template +(Issue 3: "Quero visualizar os templates criados") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | +| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | +## Regras de Negócio - Visualizar Templates +(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") + +| Código | Descrição | +|--------|----------------------------------------------------------------------------------------------------| +| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | +| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | + + + +## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) +(Issue 4: Importar dados do SIGAA) +(Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | +| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | +| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | +| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | + +## Regras de Negócio - Gerenciamento de Relatórios e Resultados +(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | +| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | +| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | + +## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) +(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | +| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | +| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | +| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | +| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | +| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | +| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | +| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | + +## Regras de Negócio - Gerenciamento de Turmas por Departamento +(Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) + +| Código | Descrição | +|--------|---------------------------------------------------------------------------------------------------------------------| +| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | + + + + +## Quem ficou responsável por cada cenário BDD em relação as US/Issues? + +#[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe +#[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe +#[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) Caroline +#[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) Mário +#[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) Célio +#[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) Caroline +#[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) Luís Filipe +#[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) Mário +#[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) Célio +#[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) Célio +#[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) (Caroline ou Luís Filipe) +#[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) Célio +#[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) Caroline +#[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) Mário +#[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) Mário +#[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) (Caroline ou Luís Filipe) + +--- + +# 📊 Métrica Velocity da Sprint 1 + +| História/Issue | Pontos | +| ---------------- | ------------------- | +| US / #02 | 1 | +| US / #03 | 1 | +| US / #04 | 1 | +| US / #05 | 1 | +| US / #06 | 1 | +| US / #07 | 1 | +| US / #08 | 1 | +| US / #09 | 1 | +| US / #10 | 1 | +| US / #11 | 1 | +| US / #12 | 1 | +| US / #13 | 1 | +| US / #14 | 1 | +| US / #15 | 1 | +| US / #16 | 1 | +| US / #17 | 1 | +| **Total** | **Story Points** | +| **16 US/Issues** | **16 Story Points** | + +--- + +# 🌿 Política de Branching Utilizada pelo Grupo + +Sprint Branching + Feature Branching (variação do GitLab Flow): + +- A equipe cria uma branch representando a sprint a partir da main. + +- Todas as feature branches da sprint nascem a partir dela. + +- No final da sprint, tudo é consolidado e mergeado para a branch da sprint. From 82af6b9f5dcbbedfb412e16a0b20231ec555ab16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:26:16 -0300 Subject: [PATCH 31/42] Delete Wiki.md --- Wiki.md | 240 -------------------------------------------------------- 1 file changed, 240 deletions(-) delete mode 100644 Wiki.md diff --git a/Wiki.md b/Wiki.md deleted file mode 100644 index 729449611a..0000000000 --- a/Wiki.md +++ /dev/null @@ -1,240 +0,0 @@ -# 📝 Wiki do Projeto – Sprint 1 - -**Grupo 1 – Engenharia de Software** -**Integrantes:** - -| Nome | Matrícula | -| :---------- | :-------- | -| Caroline | 232050975 | -| Célio | 211010350 | -| Luís Filipe | 190091975 | -| Mário | 231035778 | - -# 📌 Nome do Projeto - -**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC** - -# 📌 Escopo do Projeto - -O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. -O projeto contempla funcionalidades de cadastro de usuários, redefinição de senha, importação de base de dados do SIGAA, visualização de formulários, criação de formulários, criação de templates para formulários e download de resultados dos relatórios. - -# 🔰 Papéis na Sprint 1 - -● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o -Cucumber. -● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação -(BDD) no repositório principal. -● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a -matrícula dos integrantes. -● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo -as informações sobre a Sprint 1. - -## 🧑‍💼 Scrum Master - -Caroline, Célio, Luís Filipe e Mário. - -## 🧑‍💻 Product Owner - -Caroline, Célio, Luís Filipe e Mário. - -# Quais funcionalidades serão desenvolvidas? - -Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. -As US desta sprint são: -[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) -[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) -[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) -[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) -[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) -[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) -[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) -[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) -[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) -[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) -[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) -[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) -[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) -[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) -[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) -[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) - -# Quais serão as regras de negócio para cada funcionalidade? -## Regras de Negócio - Redefinição de Senha -(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-RS-01 | O usuário deve informar um e-mail cadastrado para solicitar a redefinição de senha. | -| RN-RS-02 | Caso o e-mail **não exista** no sistema, exibir mensagem de sucesso genérica ("Se este e-mail estiver cadastrado...") para evitar enumeração de usuários. | -| RN-RS-03 | Se o e-mail existir, gerar um **token único** de redefinição e enviá-lo por e-mail ao usuário. | -| RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | -| RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | -| RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | -## Regras de Negócio - Definição de Senha (Primeiro Acesso) -(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-DS-01 | O link de definição de senha é de **uso único**. | -| RN-DS-02 | A senha deve ter no mínimo **8 caracteres**, contendo letras maiúsculas, minúsculas e números. | -| RN-DS-03 | Os campos **"Nova Senha"** e **"Confirmar Senha"** devem ser idênticos; caso contrário, exibir erro. | -| RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | - -## Regras de Negócio - Cadastro de Usuários via Importação -(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-C-01 | A funcionalidade de importação só está acessível para usuários com perfil **"Admin"**. | -| RN-C-02 | Aceitar **apenas** arquivos no formato **.json**. Qualquer outro formato (ex: .pdf, .csv) → "Formato de arquivo inválido". | -| RN-C-03 | O arquivo deve ser um **JSON válido** (sintaxe correta). Erros de sintaxe → "O arquivo não é um JSON válido". | -| RN-C-04 | Cada objeto de usuário deve conter **obrigatoriamente** as chaves `"matricula"` e `"email"`. Falta de qualquer uma → rejeitar importação. | -| RN-C-05 | As chaves devem ter tipos corretos (ex: `"matricula"` deve ser número/string numérica válida). | -| RN-C-06 | Se a matrícula **não existir** no banco, criar novo usuário com status **"Pendente"**. | -| RN-C-07 | **Não** disparar automaticamente o e-mail de definição de senha ao criar usuário "Pendente" via importação. | -| RN-C-08 | Se a matrícula já existir, **não criar duplicata**. | -| RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | - -## Regras de Negócio - Sistema de Login -(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-L-01 | O usuário deve poder se autenticar usando **e-mail** ou **número de matrícula** no mesmo campo de login. | -| RN-L-02 | Os campos **"E-mail ou Matrícula"** e **"Senha"** são de preenchimento obrigatório. | -| RN-L-03 | Em caso de e-mail/matrícula ou senha incorretos, exibir mensagem genérica **"E-mail ou senha inválidos"** (nunca informar qual dos dois está errado). | -| RN-L-04 | Usuários com perfil **"Admin"** devem ter a opção **"Gerenciamento"** exibida no menu lateral. | -| RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | -| RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | - -## Regras de Negócio - Criar Formulário (Template de Questões) -(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | -| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | -## Regras de Negócio - Criar Template de Formulário -(Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | -| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | -## Regras de Negócio - Editar Template -(Issue 3: "Quero visualizar os templates criados") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | -| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | -## Regras de Negócio - Visualizar Templates -(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | -| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | - - - -## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) -(Issue 4: Importar dados do SIGAA) -(Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | -| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | -| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | -| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | - -## Regras de Negócio - Gerenciamento de Relatórios e Resultados -(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | -| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | -| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | - -## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) -(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | -| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | -| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | -| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | -| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | -| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | -| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | -| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | - -## Regras de Negócio - Gerenciamento de Turmas por Departamento -(Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | - - - - -## Quem ficou responsável por cada cenário BDD em relação as US/Issues? - -#[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe -#[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe -#[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) Caroline -#[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) Mário -#[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) Célio -#[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) Caroline -#[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) Luís Filipe -#[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) Mário -#[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) Célio -#[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) Célio -#[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) (Caroline ou Luís Filipe) -#[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) Célio -#[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) Caroline -#[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) Mário -#[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) Mário -#[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) (Caroline ou Luís Filipe) - ---- - -# 📊 Métrica Velocity da Sprint 1 - -| História/Issue | Pontos | -| ---------------- | ------------------- | -| US / #02 | 1 | -| US / #03 | 1 | -| US / #04 | 1 | -| US / #05 | 1 | -| US / #06 | 1 | -| US / #07 | 1 | -| US / #08 | 1 | -| US / #09 | 1 | -| US / #10 | 1 | -| US / #11 | 1 | -| US / #12 | 1 | -| US / #13 | 1 | -| US / #14 | 1 | -| US / #15 | 1 | -| US / #16 | 1 | -| US / #17 | 1 | -| **Total** | **Story Points** | -| **16 US/Issues** | **16 Story Points** | - ---- - -# 🌿 Política de Branching Utilizada pelo Grupo - -Sprint Branching + Feature Branching (variação do GitLab Flow): - -- A equipe cria uma branch representando a sprint a partir da main. - -- Todas as feature branches da sprint nascem a partir dela. - -- No final da sprint, tudo é consolidado e mergeado para a branch da sprint. From c0e3eda800bf1c48048bcdf7190300db1a34ab2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:26:27 -0300 Subject: [PATCH 32/42] Delete Wiki2.md --- Wiki2.md | 240 ------------------------------------------------------- 1 file changed, 240 deletions(-) delete mode 100644 Wiki2.md diff --git a/Wiki2.md b/Wiki2.md deleted file mode 100644 index 729449611a..0000000000 --- a/Wiki2.md +++ /dev/null @@ -1,240 +0,0 @@ -# 📝 Wiki do Projeto – Sprint 1 - -**Grupo 1 – Engenharia de Software** -**Integrantes:** - -| Nome | Matrícula | -| :---------- | :-------- | -| Caroline | 232050975 | -| Célio | 211010350 | -| Luís Filipe | 190091975 | -| Mário | 231035778 | - -# 📌 Nome do Projeto - -**CAMAAR – Sistema para avaliação de atividades acadêmicas remotas do CIC** - -# 📌 Escopo do Projeto - -O sistema **CAMAAR** tem como objetivo auxiliar na avaliação acadêmica de atividades, tarefas e outras atividades remotas do CIC. -O projeto contempla funcionalidades de cadastro de usuários, redefinição de senha, importação de base de dados do SIGAA, visualização de formulários, criação de formulários, criação de templates para formulários e download de resultados dos relatórios. - -# 🔰 Papéis na Sprint 1 - -● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o -Cucumber. -● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação -(BDD) no repositório principal. -● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a -matrícula dos integrantes. -● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo -as informações sobre a Sprint 1. - -## 🧑‍💼 Scrum Master - -Caroline, Célio, Luís Filipe e Mário. - -## 🧑‍💻 Product Owner - -Caroline, Célio, Luís Filipe e Mário. - -# Quais funcionalidades serão desenvolvidas? - -Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. -As US desta sprint são: -[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) -[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) -[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) -[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) -[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) -[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) -[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) -[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) -[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) -[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) -[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) -[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) -[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) -[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) -[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) -[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) - -# Quais serão as regras de negócio para cada funcionalidade? -## Regras de Negócio - Redefinição de Senha -(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-RS-01 | O usuário deve informar um e-mail cadastrado para solicitar a redefinição de senha. | -| RN-RS-02 | Caso o e-mail **não exista** no sistema, exibir mensagem de sucesso genérica ("Se este e-mail estiver cadastrado...") para evitar enumeração de usuários. | -| RN-RS-03 | Se o e-mail existir, gerar um **token único** de redefinição e enviá-lo por e-mail ao usuário. | -| RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | -| RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | -| RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | -## Regras de Negócio - Definição de Senha (Primeiro Acesso) -(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-DS-01 | O link de definição de senha é de **uso único**. | -| RN-DS-02 | A senha deve ter no mínimo **8 caracteres**, contendo letras maiúsculas, minúsculas e números. | -| RN-DS-03 | Os campos **"Nova Senha"** e **"Confirmar Senha"** devem ser idênticos; caso contrário, exibir erro. | -| RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | - -## Regras de Negócio - Cadastro de Usuários via Importação -(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-C-01 | A funcionalidade de importação só está acessível para usuários com perfil **"Admin"**. | -| RN-C-02 | Aceitar **apenas** arquivos no formato **.json**. Qualquer outro formato (ex: .pdf, .csv) → "Formato de arquivo inválido". | -| RN-C-03 | O arquivo deve ser um **JSON válido** (sintaxe correta). Erros de sintaxe → "O arquivo não é um JSON válido". | -| RN-C-04 | Cada objeto de usuário deve conter **obrigatoriamente** as chaves `"matricula"` e `"email"`. Falta de qualquer uma → rejeitar importação. | -| RN-C-05 | As chaves devem ter tipos corretos (ex: `"matricula"` deve ser número/string numérica válida). | -| RN-C-06 | Se a matrícula **não existir** no banco, criar novo usuário com status **"Pendente"**. | -| RN-C-07 | **Não** disparar automaticamente o e-mail de definição de senha ao criar usuário "Pendente" via importação. | -| RN-C-08 | Se a matrícula já existir, **não criar duplicata**. | -| RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | - -## Regras de Negócio - Sistema de Login -(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") - -| Código | Descrição | -|------------|---------------------------------------------------------------------------------------------------------------------| -| RN-L-01 | O usuário deve poder se autenticar usando **e-mail** ou **número de matrícula** no mesmo campo de login. | -| RN-L-02 | Os campos **"E-mail ou Matrícula"** e **"Senha"** são de preenchimento obrigatório. | -| RN-L-03 | Em caso de e-mail/matrícula ou senha incorretos, exibir mensagem genérica **"E-mail ou senha inválidos"** (nunca informar qual dos dois está errado). | -| RN-L-04 | Usuários com perfil **"Admin"** devem ter a opção **"Gerenciamento"** exibida no menu lateral. | -| RN-L-05 | Usuários com perfil diferente de "Admin" (ex: Aluno, Professor) **não devem** ver a opção "Gerenciamento". | -| RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | - -## Regras de Negócio - Criar Formulário (Template de Questões) -(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | -| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | -## Regras de Negócio - Criar Template de Formulário -(Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | -| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | -## Regras de Negócio - Editar Template -(Issue 3: "Quero visualizar os templates criados") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | -| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | -## Regras de Negócio - Visualizar Templates -(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") - -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | -| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | - - - -## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) -(Issue 4: Importar dados do SIGAA) -(Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | -| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | -| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | -| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | - -## Regras de Negócio - Gerenciamento de Relatórios e Resultados -(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | -| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | -| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | - -## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) -(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | -| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | -| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | -| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | -| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | -| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | -| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | -| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | - -## Regras de Negócio - Gerenciamento de Turmas por Departamento -(Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) - -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | - - - - -## Quem ficou responsável por cada cenário BDD em relação as US/Issues? - -#[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) Luís Filipe -#[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) Luís Filipe -#[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) Caroline -#[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) Mário -#[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) Célio -#[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) Caroline -#[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) Luís Filipe -#[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) Mário -#[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) Célio -#[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) Célio -#[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) (Caroline ou Luís Filipe) -#[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) Célio -#[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) Caroline -#[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) Mário -#[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) Mário -#[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) (Caroline ou Luís Filipe) - ---- - -# 📊 Métrica Velocity da Sprint 1 - -| História/Issue | Pontos | -| ---------------- | ------------------- | -| US / #02 | 1 | -| US / #03 | 1 | -| US / #04 | 1 | -| US / #05 | 1 | -| US / #06 | 1 | -| US / #07 | 1 | -| US / #08 | 1 | -| US / #09 | 1 | -| US / #10 | 1 | -| US / #11 | 1 | -| US / #12 | 1 | -| US / #13 | 1 | -| US / #14 | 1 | -| US / #15 | 1 | -| US / #16 | 1 | -| US / #17 | 1 | -| **Total** | **Story Points** | -| **16 US/Issues** | **16 Story Points** | - ---- - -# 🌿 Política de Branching Utilizada pelo Grupo - -Sprint Branching + Feature Branching (variação do GitLab Flow): - -- A equipe cria uma branch representando a sprint a partir da main. - -- Todas as feature branches da sprint nascem a partir dela. - -- No final da sprint, tudo é consolidado e mergeado para a branch da sprint. From 0ee2af19d13be4c7a060f706546c0955c5ddc27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:52:21 -0300 Subject: [PATCH 33/42] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20-=20pontos=20das?= =?UTF-8?q?=20BDDs=20=20-=20Wiki?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atualização de pontos das histórias de usuário para as métricas da sprint na Wiki --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5d99c9730e..f24a961e80 100644 --- a/README.md +++ b/README.md @@ -208,24 +208,24 @@ As US desta sprint são: | História/Issue | Pontos | | ---------------- | ------------------- | -| US / #02 | 1 | +| US / #02 | 2 | | US / #03 | 1 | -| US / #04 | 1 | -| US / #05 | 1 | -| US / #06 | 1 | -| US / #07 | 1 | -| US / #08 | 1 | -| US / #09 | 1 | -| US / #10 | 1 | -| US / #11 | 1 | -| US / #12 | 1 | -| US / #13 | 1 | -| US / #14 | 1 | -| US / #15 | 1 | -| US / #16 | 1 | -| US / #17 | 1 | +| US / #04 | 3 | +| US / #05 | 2 | +| US / #06 | 3 | +| US / #07 | 2 | +| US / #08 | 3 | +| US / #09 | 3 | +| US / #10 | 2 | +| US / #11 | 2 | +| US / #12 | 3 | +| US / #13 | 3 | +| US / #14 | 3 | +| US / #15 | 2 | +| US / #16 | 3 | +| US / #17 | 3 | | **Total** | **Story Points** | -| **16 US/Issues** | **16 Story Points** | +| **16 US/Issues** | **39 Story Points** | --- From 95148635e452c310a1f0eed54dbd7dbf8052e65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:10:52 -0300 Subject: [PATCH 34/42] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20BDDs=20-=20links?= =?UTF-8?q?=20com=20os=20nomes=20das=20Issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f24a961e80..8279c8a91d 100644 --- a/README.md +++ b/README.md @@ -42,22 +42,22 @@ Caroline, Célio, Luís Filipe e Mário. Nesta Sprint 1: 1° Etapa os integrantes irão Especificar os cenários BDD de acordo com as histórias de usuários, cada cenário BDD deve possuir pelo menos um cenário feliz e um triste. As US desta sprint são: -[02](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) -[03](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) -[04](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) -[05](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) -[06](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) -[07](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) -[08](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) -[09](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) -[10](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) -[11](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) -[12](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) -[13](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) -[14](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) -[15](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) -[16](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) -[17](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) +[02 - Edição e deleção de templates](https://github.com/mariosantos-05/CAMAAR-G1/issues/2) +[03 - Visualização dos templates criados](https://github.com/mariosantos-05/CAMAAR-G1/issues/3) +[04 - Importar dados do SIGAA](https://github.com/mariosantos-05/CAMAAR-G1/issues/4) +[05 - Responder formulário](https://github.com/mariosantos-05/CAMAAR-G1/issues/5) +[06 - Cadastrar usuários do sistema](https://github.com/mariosantos-05/CAMAAR-G1/issues/6) +[07 - Gerar relatório do Administrador](https://github.com/mariosantos-05/CAMAAR-G1/issues/7) +[08 - Criar template de formulário](https://github.com/mariosantos-05/CAMAAR-G1/issues/8) +[09 - Criar formulários de avaliação](https://github.com/mariosantos-05/CAMAAR-G1/issues/9) +[10 - Sistema de login](https://github.com/mariosantos-05/CAMAAR-G1/issues/10) +[11 - Sistema de definição de senha](https://github.com/mariosantos-05/CAMAAR-G1/issues/11) +[12 - Sistema de gerenciamento por departamento](https://github.com/mariosantos-05/CAMAAR-G1/issues/12) +[13 - Redefinição de senha](https://github.com/mariosantos-05/CAMAAR-G1/issues/13) +[14 - Atualizar base de dados com os dados do SIGAA](https://github.com/mariosantos-05/CAMAAR-G1/issues/14) +[15 - Visualização de formlários para responder](https://github.com/mariosantos-05/CAMAAR-G1/issues/15) +[16 - Visualização de Resultado dos Formulários](https://github.com/mariosantos-05/CAMAAR-G1/issues/16) +[17 - Criação de formulário para docentes ou discentes](https://github.com/mariosantos-05/CAMAAR-G1/issues/17) # Quais serão as regras de negócio para cada funcionalidade? ## Regras de Negócio - Redefinição de Senha From 243697a97f61ab299cb6b33dfb446717b953ab89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:20:08 -0300 Subject: [PATCH 35/42] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20Regras=20de=20Neg?= =?UTF-8?q?=C3=B3cio=20e=20c=C3=B3digos=20na=20Wiki?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 86 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 8279c8a91d..7f31201d8e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ As US desta sprint são: | RN-RS-04 | O token de redefinição deve expirar em **60 minutos**. | | RN-RS-05 | O token é de **uso único** – após a redefinição da senha, torna-se inválido. | | RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | + ## Regras de Negócio - Definição de Senha (Primeiro Acesso) (Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") @@ -111,74 +112,75 @@ As US desta sprint são: ## Regras de Negócio - Criar Formulário (Template de Questões) (Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN03 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | -| RN04 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | +| Código | Descrição | +|------------|----------------------------------------------------------------------------------------------------| +| RN-CF-01 | **Confirmação de Exclusão**: A ação de deletar um template exige confirmação explícita (pop-up) antes de ser executada. | +| RN-CF-02 | **Tipos de Questões**: O sistema deve permitir incluir e persistir diferentes tipos de perguntas (múltipla escolha, discursiva, etc.) no mesmo template. | + ## Regras de Negócio - Criar Template de Formulário (Issue 17: "Quero escolher criar um formulário para os docentes ou os discentes...") -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | -| RN02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | +| Código | Descrição | +|-----------|----------------------------------------------------------------------------------------------------| +| RN-CTF-01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | +| RN-CTF-02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | + ## Regras de Negócio - Editar Template (Issue 3: "Quero visualizar os templates criados") -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN05 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | -| RN06 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | +| Código | Descrição | +|-----------|----------------------------------------------------------------------------------------------------| +| RN-ET-01 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | +| RN-ET-02 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | + ## Regras de Negócio - Visualizar Templates (Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") -| Código | Descrição | -|--------|----------------------------------------------------------------------------------------------------| -| RN07 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | -| RN08 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | - - +| Código | Descrição | +|-----------|----------------------------------------------------------------------------------------------------| +| RN-VT-01 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | +| RN-VT-02 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | ## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) (Issue 4: Importar dados do SIGAA) (Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | -| RN14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | -| RN15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | -| RN16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | +| Código | Descrição | +|-----------|---------------------------------------------------------------------------------------------------------------------| +| RN-IDS-13 | Para cada item do JSON, verificar a chave única (ex: matrícula do aluno ou código da disciplina):
• Se **não existir** → criar o registro.
• Se **já existir** → ignorar o item (não atualizar nem duplicar). | +| RN-IDS-14 | Esta é uma operação de **"apenas adicionar"**, usada para alimentar a base sem risco de sobrescrever dados já alterados manualmente. | +| RN-IDS-15 | Aceitar somente arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado com mensagem de erro. | +| RN-IDS-16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | ## Regras de Negócio - Gerenciamento de Relatórios e Resultados (Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN10 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | -| RN11 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | -| RN12 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | +| Código | Descrição | +|-----------|---------------------------------------------------------------------------------------------------------------------| +| RN-GR-01 | O acesso à página **"Gerenciamento → Resultados"** e todas as suas funcionalidades é restrito exclusivamente a usuários com papel **"Administrador"**. | +| RN-GR-02 | Usuários sem perfil Administrador **não devem ver** o link da página. Caso tentem acessar diretamente a URL, devem ser bloqueados e redirecionados ao seu dashboard. | +| RN-GR-03 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | ## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) (Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN02 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | -| RN03 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | -| RN04 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | -| RN05 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | -| RN06 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | -| RN07 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | -| RN08 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | -| RN09 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | +| Código | Descrição | +|-----------|---------------------------------------------------------------------------------------------------------------------| +| RN-ADE-01 | Se o item (aluno, turma, etc.) do JSON **não existir** no banco, o sistema deve criá-lo. | +| RN-ADE-02 | Se o item do JSON **já existir** no banco, o sistema deve atualizar o registro existente com os dados do JSON. | +| RN-ADE-03 | O sistema **nunca** deve criar duplicatas – a ação é sempre de correção/atualização do registro existente. | +| RN-ADE-04 | Aceitar apenas arquivos com extensão **.json**. Qualquer outro formato deve ser rejeitado. | +| RN-ADE-05 | O arquivo .json deve ser sintaticamente válido. Caso contrário, a importação deve ser rejeitada. | +| RN-ADE-06 | O JSON deve conter todas as chaves obrigatórias esperadas. Se algum item estiver sem chave obrigatória (ex: matrícula), a importação deve falhar. | +| RN-ADE-07 | Após importação bem-sucedida, exibir mensagem de sucesso clara ao administrador. | +| RN-ADE-08 | Após falha na importação (qualquer motivo), exibir mensagem de erro detalhando o problema. | ## Regras de Negócio - Gerenciamento de Turmas por Departamento (Issue 12: Quero gerenciar somente as turmas do departamento o qual eu pertenço) -| Código | Descrição | -|--------|---------------------------------------------------------------------------------------------------------------------| -| RN01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | +| Código | Descrição | +|-----------|---------------------------------------------------------------------------------------------------------------------| +| RN-GTD-01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | From e194d5de7d5ed59882fd86b7bd601c343446ace2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:26:44 -0300 Subject: [PATCH 36/42] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20de=20numera=C3=A7?= =?UTF-8?q?=C3=A3o=20e=20nome=20das=20issues=20-=20RNs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7f31201d8e..9f05895418 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ As US desta sprint são: # Quais serão as regras de negócio para cada funcionalidade? ## Regras de Negócio - Redefinição de Senha -(Issue 1: "Quero redefinir uma senha... a partir do e-mail recebido...") +(Issue 13: "Quero redefinir uma senha... a partir do e-mail recebido...") | Código | Descrição | |------------|---------------------------------------------------------------------------------------------------------------------| @@ -73,7 +73,7 @@ As US desta sprint são: | RN-RS-06 | A nova senha deve obedecer às regras de complexidade do sistema (ver RN-DS-02). | ## Regras de Negócio - Definição de Senha (Primeiro Acesso) -(Issue 2: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") +(Issue 11: "Quero definir uma senha... a partir do e-mail do sistema de solicitação de cadastro...") | Código | Descrição | |------------|---------------------------------------------------------------------------------------------------------------------| @@ -98,7 +98,7 @@ As US desta sprint são: | RN-C-09 | Se a matrícula já existir, **atualizar** os dados do usuário (ex: atualizar e-mail se diferente no JSON). | ## Regras de Negócio - Sistema de Login -(Issue 3: "Quero acessar o sistema utilizando um e-mail ou matrícula...") +(Issue 10: "Quero acessar o sistema utilizando um e-mail ou matrícula...") | Código | Descrição | |------------|---------------------------------------------------------------------------------------------------------------------| @@ -110,7 +110,7 @@ As US desta sprint são: | RN-L-06 | O login só é permitido se o status da conta do usuário for **"Ativo"** (ou seja, após a primeira definição de senha). | ## Regras de Negócio - Criar Formulário (Template de Questões) -(Issue 8: "Quero criar um template de formulário contendo as questões do formulário...") +(Issue 09: "Quero criar um template de formulário contendo as questões do formulário...") | Código | Descrição | |------------|----------------------------------------------------------------------------------------------------| @@ -125,16 +125,16 @@ As US desta sprint são: | RN-CTF-01 | **Obrigatoriedade de Título**: Não é permitido criar ou salvar um template com o campo "Nome/Título" vazio. | | RN-CTF-02 | **Imutabilidade Histórica**: A edição de um template **não pode** alterar a estrutura ou os dados de formulários já respondidos (instâncias antigas permanecem inalteradas). | -## Regras de Negócio - Editar Template -(Issue 3: "Quero visualizar os templates criados") +## Regras de Negócio - Visualizar Templates +(Issue 03: "Quero visualizar os templates criados") | Código | Descrição | |-----------|----------------------------------------------------------------------------------------------------| | RN-ET-01 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | | RN-ET-02 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | -## Regras de Negócio - Visualizar Templates -(Issue 2: "Quero editar e/ou deletar um template que eu criei sem afetar...") +## Regras de Negócio - Editar e Deletar Template +(Issue 02: "Quero editar e/ou deletar um template que eu criei sem afetar...") | Código | Descrição | |-----------|----------------------------------------------------------------------------------------------------| @@ -142,7 +142,7 @@ As US desta sprint são: | RN-VT-02 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | ## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) -(Issue 4: Importar dados do SIGAA) +(Issue 04: Importar dados do SIGAA) (Quero importar dados de turmas, matérias e participantes do SIGAA caso não existam na base de dados atual) | Código | Descrição | @@ -153,7 +153,7 @@ As US desta sprint são: | RN-IDS-16 | O arquivo .json deve ser sintaticamente válido. Erro de sintaxe → rejeição imediata com mensagem de erro clara. | ## Regras de Negócio - Gerenciamento de Relatórios e Resultados -(Issue 7: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) +(Issue 07: Gerar relatório do administrador – Quero baixar um arquivo CSV contendo os resultados de um formulário) | Código | Descrição | |-----------|---------------------------------------------------------------------------------------------------------------------| @@ -162,7 +162,7 @@ As US desta sprint são: | RN-GR-03 | Ao solicitar o download dos resultados, o sistema deve gerar e oferecer um arquivo no formato **CSV**. | ## Regras de Negócio - Atualizar Dados Existentes (via SIGAA) -(Issue 4: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) +(Issue 14: Quero atualizar a base de dados já existente com os dados atuais do SIGAA) | Código | Descrição | |-----------|---------------------------------------------------------------------------------------------------------------------| From 9e47e928725b3b17416b62cb78196308123a4bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:30:40 -0300 Subject: [PATCH 37/42] =?UTF-8?q?Conserto=20-=20n=C3=BAmero=20da=20issue?= =?UTF-8?q?=20na=20RN-06?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f05895418..1410243120 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ As US desta sprint são: | RN-DS-04 | A conta só muda de status **"Pendente" → "Ativo"** após a definição bem-sucedida da senha (cadastro efetivado). | ## Regras de Negócio - Cadastro de Usuários via Importação -(Issue 4: "Quero cadastrar participantes... ao importar dados de usuarios novos...") +(Issue 06: "Quero cadastrar participantes... ao importar dados de usuarios novos...") | Código | Descrição | |------------|---------------------------------------------------------------------------------------------------------------------| From 4172d305f9fa2fdadfce8c554bc289f1a4aa7407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:43:37 -0300 Subject: [PATCH 38/42] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrigindo a pontuação total de SP --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1410243120..cdde093a4d 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ As US desta sprint são: | US / #16 | 3 | | US / #17 | 3 | | **Total** | **Story Points** | -| **16 US/Issues** | **39 Story Points** | +| **16 US/Issues** | **40 Story Points** | --- From 2940c5f6ec3b6097e9dc746fec24edafbc957af9 Mon Sep 17 00:00:00 2001 From: Mario Santos <76963308+mariosantos-05@users.noreply.github.com> Date: Tue, 18 Nov 2025 18:00:17 -0300 Subject: [PATCH 39/42] Update README Added business rules for evaluation forms and responses. --- README.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cdde093a4d..c6d10bc45c 100644 --- a/README.md +++ b/README.md @@ -182,8 +182,45 @@ As US desta sprint são: |-----------|---------------------------------------------------------------------------------------------------------------------| | RN-GTD-01 | Se um usuário (administrador de departamento ou não) tentar acessar diretamente via URL os dados de turmas de outro departamento, o sistema deve redirecioná-lo imediatamente para sua página principal (Dashboard). | - - +## Regras de Negócio - Criar Formulário de Avaliação +(Issue 09: "Criar um formulário de avaliação baseado em um template para turmas selecionadas") + +| Código | Descrição | +|--------|-----------| +| RN-CFA-01 | **Seleção Obrigatória de Turmas**: Não é permitido criar formulários se nenhuma turma for selecionada; o sistema deve exibir a mensagem de erro "Nenhuma turma selecionada." | +| RN-CFA-02 | **Seleção Obrigatória de Template**: O sistema deve impedir a criação de formulários caso nenhum template seja selecionado, exibindo a mensagem "Nenhum template selecionado." | +| RN-CFA-03 | **Criação em Lote por Turma**: O sistema deve gerar individualmente um formulário para cada turma selecionada quando solicitado. | +| RN-CFA-04 | **Confirmação de Sucesso**: Após criar os formulários, o sistema deve exibir a mensagem "Formulários criados com sucesso para as turmas selecionadas." | + +## Regras de Negócio - Responder Formulário +(Issue 05: "Responder o formulário de avaliação como Participante") + +| Código | Descrição | +|--------|-----------| +| RN-RF-01 | **Disponibilidade Vinculada à Turma**: O participante só pode responder formulários das turmas em que está matriculado. | +| RN-RF-02 | **Existência de Formulário Ativo**: O sistema só permite acesso e envio se houver um formulário ativo disponível para a turma. | +| RN-RF-03 | **Validação de Campos Obrigatórios**: O sistema deve impedir o envio caso campos obrigatórios não sejam preenchidos, exibindo erro. | +| RN-RF-04 | **Registro de Respostas**: O sistema deve registrar todas as respostas submetidas pelo participante. | +| RN-RF-05 | **Confirmação de Envio**: Após envio bem-sucedido, o sistema deve exibir "Seu formulário foi enviado com sucesso." | + +## Regras de Negócio - Visualização de Formulários Pendentes +(Issue 15: "Visualizar os formulários não respondidos das turmas em que o participante está matriculado") + +| Código | Descrição | +|--------|-----------| +| RN-VFP-01 | **Exibição Apenas do que Não foi Respondido**: O sistema deve listar somente formulários pendentes. | +| RN-VFP-01 | **Segmentação por Turma Matriculada**: O participante só visualiza formulários das turmas nas quais está matriculado. | +| RN-VFP-01 | **Contador de Formulários Pendentes**: O sistema deve exibir o total de formulários pendentes com mensagem informativa. | +| RN-VFP-01 | **Estado de Lista Vazia**: Na ausência de formulários pendentes, exibir "Você não possui formulários pendentes." | + +## Regras de Negócio - Visualizar Resultados dos Formulários +(Issue 16: "Visualização dos formulários criados pelo Administrador") + +| Código | Descrição | +|--------|-----------| +| RN-VRF-01 | **Lista de Formulários Criados**: O administrador deve visualizar os formulários criados organizados por turma. | +| RN-VRF-02 | **Contador de Formulários Criados**: O sistema deve exibir o total de formulários criados, como "Existem X formulários criados." | +| RN-VRF-03 | **Acesso aos Detalhes**: O administrador deve poder visualizar perguntas, respostas e estatísticas de cada formulário selecionado. | ## Quem ficou responsável por cada cenário BDD em relação as US/Issues? From 9902f8048cb862707c0e1584b99992191e411708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 23:12:43 -0300 Subject: [PATCH 40/42] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atualizações de papéis na Sprint 1 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6d10bc45c..6cf540ce12 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,11 @@ O projeto contempla funcionalidades de cadastro de usuários, redefinição de s ● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o Cucumber. -● A definir - Abrir uma Pull Request com as especificações dos testes de aceitação +● Mário - Abrir uma Pull Request com as especificações dos testes de aceitação (BDD) no repositório principal. -● A definir - Entregar arquivo .txt contendo um link para o repositório, o nome e a +● Mário - Entregar arquivo .txt contendo um link para o repositório, o nome e a matrícula dos integrantes. -● Luís Filipe - Adicionar um arquivo Markdown como Wiki no fork do grupo, contendo +● Caroline, Célio, Luís Filipe, Mário - Criar um arquivo Markdown como Wiki, contendo as informações sobre a Sprint 1. ## 🧑‍💼 Scrum Master From d4c96992bffe7a772aa03da3040d9b8ff2521b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Filipe?= <135170965+luisfilipe3@users.noreply.github.com> Date: Tue, 18 Nov 2025 23:17:13 -0300 Subject: [PATCH 41/42] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atualização estética. --- README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6cf540ce12..0d9270fc3d 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,22 @@ O projeto contempla funcionalidades de cadastro de usuários, redefinição de s # 🔰 Papéis na Sprint 1 -● Caroline, Célio, Luís Filipe e Mário - Especificar os cenários BDD das histórias de usuário usando o -Cucumber. -● Mário - Abrir uma Pull Request com as especificações dos testes de aceitação +● Especificar os cenários BDD das histórias de usuário usando o +Cucumber. +Responsáveis: Caroline, Célio, Luís Filipe e Mário. + +● Abrir uma Pull Request com as especificações dos testes de aceitação (BDD) no repositório principal. -● Mário - Entregar arquivo .txt contendo um link para o repositório, o nome e a +Responsável: Mário + +● Entregar arquivo .txt contendo um link para o repositório, o nome e a matrícula dos integrantes. -● Caroline, Célio, Luís Filipe, Mário - Criar um arquivo Markdown como Wiki, contendo -as informações sobre a Sprint 1. +Responsável: Mário + +● Criar um arquivo Markdown como Wiki, contendo +as informações sobre a Sprint 1. +Responsáveis: Caroline, Célio, Luís Filipe e Mário. + ## 🧑‍💼 Scrum Master From a5262e73578f7a6c8d4ce0d3548b1b693f93238f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lio=20Eduardo?= <59587358+celio-eduardo@users.noreply.github.com> Date: Tue, 18 Nov 2025 23:58:30 -0300 Subject: [PATCH 42/42] =?UTF-8?q?Corre=C3=A7=C3=A3o=20-=20ET=20e=20VT=20tr?= =?UTF-8?q?ocados=20nas=20RNs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0d9270fc3d..7058847ca8 100644 --- a/README.md +++ b/README.md @@ -138,16 +138,16 @@ As US desta sprint são: | Código | Descrição | |-----------|----------------------------------------------------------------------------------------------------| -| RN-ET-01 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | -| RN-ET-02 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | +| RN-VT-01 | **Condicionalidade de Campos**: O campo "Turma" deve ser **obrigatório** quando o público-alvo for "Discentes" e **oculto** quando for "Docentes". | +| RN-VT-02 | **Segmentação de Envio**: O formulário gerado deve ser enviado **apenas** para os usuários vinculados à turma selecionada. | ## Regras de Negócio - Editar e Deletar Template (Issue 02: "Quero editar e/ou deletar um template que eu criei sem afetar...") | Código | Descrição | |-----------|----------------------------------------------------------------------------------------------------| -| RN-VT-01 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | -| RN-VT-02 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | +| RN-ET-01 | **Estado de Lista Vazia**: Quando não houver templates cadastrados, exibir a mensagem "Nenhum template foi criado" em vez de uma lista em branco. | +| RN-ET-02 | **Ações de Gerenciamento**: Cada item da lista deve exibir botões individuais de **"Editar"** e **"Deletar"**. | ## Regras de Negócio - Importação de Dados do SIGAA (Apenas Adicionar) (Issue 04: Importar dados do SIGAA)