diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..868245c --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,31 @@ +FROM ruby:3.4.1 + +# Install system dependencies +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y \ + build-essential \ + git \ + libpq-dev \ + postgresql-client \ + libvips \ + pkg-config \ + curl \ + vim \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives + +# Set working directory +WORKDIR /app + +# Install application dependencies +COPY Gemfile Gemfile.lock ./ +RUN bundle install + +# Add a script to be executed every time the container starts +COPY entrypoint.dev.sh /usr/bin/ +RUN chmod +x /usr/bin/entrypoint.dev.sh +ENTRYPOINT ["entrypoint.dev.sh"] + +EXPOSE 3000 + +# Start the main process +CMD ["rails", "server", "-b", "0.0.0.0"] \ No newline at end of file diff --git a/app/jobs/sailors_log_slack_notification_job.rb b/app/jobs/sailors_log_notify_job.rb similarity index 59% rename from app/jobs/sailors_log_slack_notification_job.rb rename to app/jobs/sailors_log_notify_job.rb index 4503887..19cd4a3 100644 --- a/app/jobs/sailors_log_slack_notification_job.rb +++ b/app/jobs/sailors_log_notify_job.rb @@ -1,11 +1,13 @@ -class SailorsLogSlackNotificationJob < ApplicationJob +class SailorsLogNotifyJob < ApplicationJob queue_as :default - def perform(sailors_log_slack_notification) - slack_uid = sailors_log_slack_notification.slack_uid - slack_channel_id = sailors_log_slack_notification.slack_channel_id - project_name = sailors_log_slack_notification.project_name - project_duration = sailors_log_slack_notification.project_duration + def perform(sailors_log_slack_notification_id) + slsn = SailorsLogSlackNotification.find(sailors_log_slack_notification_id) + + slack_uid = slsn.slack_uid + slack_channel_id = slsn.slack_channel_id + project_name = slsn.project_name + project_duration = slsn.project_duration kudos_message = [ "Great work!", @@ -23,7 +25,7 @@ class SailorsLogSlackNotificationJob < ApplicationJob message = ":boat: <@#{slack_uid}> just coded 1 more hour on #{project_name} (total: #{hours}hrs). #{kudos_message}" - response = HTTP.auth("Bearer #{ENV['SLACK_BOT_TOKEN']}") + response = HTTP.auth("Bearer #{ENV['SLACK_BOT_OAUTH_TOKEN']}") .post("https://slack.com/api/chat.postMessage", json: { channel: slack_channel_id, @@ -32,9 +34,10 @@ class SailorsLogSlackNotificationJob < ApplicationJob response_data = JSON.parse(response.body) if response_data["ok"] - sailors_log_slack_notification.update(sent: true) + slsn.update(sent: true) else Rails.logger.error("Failed to send Slack notification: #{response_data["error"]}") + throw "Failed to send Slack notification: #{response_data["error"]}" end end end diff --git a/app/jobs/sailors_log_poll_for_changes_job.rb b/app/jobs/sailors_log_poll_for_changes_job.rb index 64e6a72..8843144 100644 --- a/app/jobs/sailors_log_poll_for_changes_job.rb +++ b/app/jobs/sailors_log_poll_for_changes_job.rb @@ -18,18 +18,17 @@ class SailorsLogPollForChangesJob < ApplicationJob if new_project_time > (log.projects_summary[project] || 0) + 1.hour # create a new SailorsLogSlackNotification log.notification_preferences.each do |preference| - new_notification << { + log.notifications << SailorsLogSlackNotification.new( slack_uid: log.slack_uid, slack_channel_id: preference.slack_channel_id, project_name: project, project_duration: new_project_time - } + ) end log.projects_summary[project] = new_project_time end end ActiveRecord::Base.transaction do - SailorsLogSlackNotification.insert_all(new_notification) log.save! if log.changed? end end diff --git a/app/models/sailors_log.rb b/app/models/sailors_log.rb index 31e2c6f..990786a 100644 --- a/app/models/sailors_log.rb +++ b/app/models/sailors_log.rb @@ -1,5 +1,7 @@ class SailorsLog < ApplicationRecord validates :slack_uid, presence: true, uniqueness: true + validates :projects_summary, presence: true + after_create :initialize_projects_summary has_many :notification_preferences, diff --git a/app/models/sailors_log_notification_preference.rb b/app/models/sailors_log_notification_preference.rb index 7cb148b..2b206ad 100644 --- a/app/models/sailors_log_notification_preference.rb +++ b/app/models/sailors_log_notification_preference.rb @@ -1,6 +1,14 @@ class SailorsLogNotificationPreference < ApplicationRecord + after_create :ensure_sailors_log_exists + belongs_to :sailors_log, class_name: "SailorsLog", foreign_key: :slack_uid, - primary_key: :slack_uid + primary_key: :slack_uid, + optional: true + private + + def ensure_sailors_log_exists + SailorsLog.find_or_create_by(slack_uid: slack_uid) + end end diff --git a/app/models/sailors_log_slack_notification.rb b/app/models/sailors_log_slack_notification.rb index 2c18553..53cd353 100644 --- a/app/models/sailors_log_slack_notification.rb +++ b/app/models/sailors_log_slack_notification.rb @@ -6,6 +6,6 @@ class SailorsLogSlackNotification < ApplicationRecord def notify_user return if sent? - SailorsLogSlackNotificationJob.perform_later(self) + SailorsLogNotifyJob.perform_later(self.id) end end diff --git a/db/schema.rb b/db/schema.rb index dc376ea..c23fe24 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -142,7 +142,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_02_22_032930) do create_table "sailors_logs", force: :cascade do |t| t.string "slack_uid", null: false - t.jsonb "projects_summary", null: false + t.jsonb "projects_summary", default: {}, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..232f1c2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +services: + web: + build: + context: . + dockerfile: Dockerfile.dev + ports: + - "3000:3000" + volumes: + - .:/app + - bundle_cache:/usr/local/bundle + environment: + - RAILS_ENV=development + - DATABASE_URL=postgres://postgres:secureorpheus123@db:5432/app_development + - POSTGRES_HOST=db + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=secureorpheus123 + depends_on: + - db + + db: + image: postgres:16 + volumes: + - harbor_postgres_data:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD=secureorpheus123 + - POSTGRES_USER=postgres + - POSTGRES_DB=app_development + ports: + - "5432:5432" + +volumes: + harbor_postgres_data: + bundle_cache: \ No newline at end of file diff --git a/entrypoint.dev.sh b/entrypoint.dev.sh new file mode 100644 index 0000000..49686e7 --- /dev/null +++ b/entrypoint.dev.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +# Remove a potentially pre-existing server.pid for Rails +rm -f /app/tmp/pids/server.pid + +# Then exec the container's main process (what's set as CMD in the Dockerfile) +exec "$@" \ No newline at end of file