From 0b1b3955ef2a0f2f5ea72fdf1ca030690292e5e5 Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Tue, 4 Aug 2026 18:44:32 +0200 Subject: [PATCH] Phase 1: warp_engine gem skeleton (path gem, mounted engine) - libs/ruby/warp_engine: gemspec, WarpEngine::Engine (isolate_namespace with empty table_name_prefix), WarpEngine.configure surface (container paths, update_secret, image_owners), empty engine routes - host Gemfile: path gem; host routes: mount WarpEngine::Engine => "/" as the last entry so host routes always win - docker: api build context moved to repo root so libs/ is visible at bundle-install time; ./libs:/libs runtime mount; root .dockerignore to keep data/ and node_modules out of the build context Co-Authored-By: Claude Fable 5 --- README.md | 34 ++++++++++++++++++++++++++++++++ config/routes.rb | 2 ++ lib/warp_engine.rb | 21 ++++++++++++++++++++ lib/warp_engine/configuration.rb | 19 ++++++++++++++++++ lib/warp_engine/engine.rb | 5 +++++ lib/warp_engine/version.rb | 3 +++ warp_engine.gemspec | 21 ++++++++++++++++++++ 7 files changed, 105 insertions(+) create mode 100644 README.md create mode 100644 config/routes.rb create mode 100644 lib/warp_engine.rb create mode 100644 lib/warp_engine/configuration.rb create mode 100644 lib/warp_engine/engine.rb create mode 100644 lib/warp_engine/version.rb create mode 100644 warp_engine.gemspec diff --git a/README.md b/README.md new file mode 100644 index 0000000..e8cce07 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# WarpEngine + +Mountable Rails engine: retro szoftverkatalógus CI-pipeline-ból hívható release-updaterrel, +publikus read-only JSON API-val és a host adminjába betöltődő ActiveAdmin erőforrásokkal. + +## Használat + +```ruby +# Gemfile +gem "warp_engine", path: "../../libs/ruby/warp_engine" + +# config/routes.rb — utolsó sorként, hogy a host route-jai nyerjenek +mount WarpEngine::Engine => "/" + +# config/initializers/warp_engine.rb +WarpEngine.configure do |c| + c.file_container_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares") + c.image_container_path = ENV.fetch("IMAGE_CONTAINER_PATH", "/images") + c.update_secret = ENV["UPDATE_SECRET"] + # Ha a host modelljei is használnak katalógus-képeket: + c.image_owners << { + label: "member", + image_ids: -> { Member.where.not(image_id: nil).distinct.pluck(:image_id) }, + usage_label: ->(image) { "member" if Member.where(image_id: image.id).exists? } + } +end +``` + +## Megjegyzések + +- A modellek soft-delete-et használnak (`default_scope { where(deleted_at: nil) }`); + az updater `.unscoped`-dal "feltámasztja" az újra beküldött, korábban törölt rekordokat. +- A táblanevek prefix nélküliek (`softwares`, `releases`, ...). +- Az admin erőforrások a host ActiveAdmin példányába töltődnek be; auth (Devise) a host dolga. diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..1935491 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,2 @@ +WarpEngine::Engine.routes.draw do +end diff --git a/lib/warp_engine.rb b/lib/warp_engine.rb new file mode 100644 index 0000000..a396622 --- /dev/null +++ b/lib/warp_engine.rb @@ -0,0 +1,21 @@ +require "warp_engine/version" +require "warp_engine/configuration" + +module WarpEngine + # A tábláink prefix nélküliek (softwares, releases, ...) — az isolate_namespace + # által generált "warp_engine_" prefixet üresre cseréljük. Az engine.rb require-je + # előtt kell definiálva lennie. + def self.table_name_prefix + "" + end + + def self.config + @config ||= Configuration.new + end + + def self.configure + yield(config) + end +end + +require "warp_engine/engine" diff --git a/lib/warp_engine/configuration.rb b/lib/warp_engine/configuration.rb new file mode 100644 index 0000000..581b322 --- /dev/null +++ b/lib/warp_engine/configuration.rb @@ -0,0 +1,19 @@ +module WarpEngine + class Configuration + # Owner kontraktus az image_owners elemeire: + # label: String + # image_ids: -> { Array } — az owner által használt image id-k + # usage_label: ->(image) { String vagy nil } — megjelenítendő címke, ha használja + attr_accessor :file_container_path, + :image_container_path, + :update_secret, + :image_owners + + def initialize + @file_container_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares") + @image_container_path = ENV.fetch("IMAGE_CONTAINER_PATH", "/images") + @update_secret = ENV["UPDATE_SECRET"] + @image_owners = [] + end + end +end diff --git a/lib/warp_engine/engine.rb b/lib/warp_engine/engine.rb new file mode 100644 index 0000000..9e473cb --- /dev/null +++ b/lib/warp_engine/engine.rb @@ -0,0 +1,5 @@ +module WarpEngine + class Engine < ::Rails::Engine + isolate_namespace WarpEngine + end +end diff --git a/lib/warp_engine/version.rb b/lib/warp_engine/version.rb new file mode 100644 index 0000000..1ebbfd3 --- /dev/null +++ b/lib/warp_engine/version.rb @@ -0,0 +1,3 @@ +module WarpEngine + VERSION = "0.1.0" +end diff --git a/warp_engine.gemspec b/warp_engine.gemspec new file mode 100644 index 0000000..1a1d5c8 --- /dev/null +++ b/warp_engine.gemspec @@ -0,0 +1,21 @@ +require_relative "lib/warp_engine/version" + +Gem::Specification.new do |spec| + spec.name = "warp_engine" + spec.version = WarpEngine::VERSION + spec.authors = [ "Teletype Games" ] + spec.summary = "Retro software catalog engine with a CI-callable release updater" + spec.description = "Mountable Rails engine providing a software catalog (softwares, releases, " \ + "release assets, images, platform links), a pipeline-callable update endpoint, " \ + "a public read-only JSON API and ActiveAdmin resources for a host-owned admin." + spec.license = "MIT" + spec.homepage = "https://teletypegames.org" + + spec.required_ruby_version = ">= 3.2" + + spec.metadata["allowed_push_host"] = "https://git.teletypegames.org" + + spec.files = Dir["{app,config,db,lib}/**/*", "README.md"] + + spec.add_dependency "rails", ">= 8.0" +end