hoang-phan

ai-worker-domain

Applies ai-worker's data model discipline. Use for any task touching app/models/**, db/migrate/**, or db/schema.rb — adding/changing fields on Project, Workflow, Stage, StageRun, PromptTemplate, JiraSync or BugsnagSync, their enums, validations, or associations.

hoang-phan 0 Actualitzat fa 4 d
GitHub

Instal·la

npx skillscat add hoang-phan/ai-worker/ai-worker-domain

Instal·la des del registre de SkillsCat.

SKILL.md

ai-worker-domain

Scope: app/models/**, db/migrate/**, db/schema.rb. Do not read app/jobs, app/services, app/controllers, or app/views for this work — the model layer has no dependency on them, except where a model calls Prompts::Renderer / AiCli::Output (noted below). db/schema.rb is the source of truth for columns; this file does not repeat them.

File map (the whole scope)

  • app/models/project.rb — a local checkout plus, for jira projects, its GitHub repo. enum :kind, { jira: 0, personal: 1 } (jira = GitHub/PR flow driven by tickets; personal = local-only, one task description per workflow, no PR). has_many :workflows, :jira_syncs, :bugsnag_syncs (all dependent: :destroy). Holds per-project settings, grouped: defaults for new workflows (skills, reviewers), Jira (site URL, assignee, tester), Slack PR review and review pings (enable flag, mention, channels, GitHub→Slack user map), UAT testing (enable flag, URL, login, delay), local pre-review testing (same shape), shared test/CI instructions, and brainstorming (goal, limits, auto-start, last-run bookkeeping). UAT and local passwords are Active Record encrypts columns. Validations are conditional on kind or on the feature's enable flag. It also refuses a local_directory that is this app's own live checkout (agents branch, merge and migrate inside the clone).
  • app/models/workflow.rb — one unit of automated work for a project. belongs_to :project, has_many :stages (ordered by position, id).
    • enum :status has 12 values (pending, implementing, reviewing, done, errored, merged, jira_updated, waiting, uat_waiting, uat_testing, uat_tested, local_testing); the integers are persisted. enum :kind is development / pr_review / runbook.
    • current_stage is the stage the scheduler should act on. For development workflows on jira projects it maps status → stage type through STAGE_TYPE_BY_STATUS; personal projects and PR-review workflows use their own single-stage maps (SIMPLE_…, PR_REVIEW_…); runbooks use current_stage_id. Stages for post-merge Jira update, UAT test and local test are created lazily the first time they're needed.
    • after_create seeds stages by kind/project type: jira development → implementation + pr_check; personal → task; pr_review → pr_review; runbook → copies of another runbook's stages (copy_stages_from_id) or none.
    • Runbook state machine lives here: start_runbook!, advance! (the Next button / auto_advance), next/previous stage helpers, awaiting_next, auto_run, and variables (JSON; edited as NAME=value lines via variables_text; input_variables vs stage-emitted output_variable_names).
    • Other responsibilities: agent-run tracking columns (pid, log path, start time, log offset, processing); reference images stored as plain files under tmp/workflow_images/<id> (not Active Storage) and exposed to prompts via {IMAGES}; resume_status (where an errored workflow goes back to); label / brief display text; skill_list; tracks_jira_after_merge?; QUEUED_STATUSES / queued scope used by brainstorming; UAT schedule (uat_test_at) and local-test feedback text.
    • Validations depend on kind and project kind (ticket/branch/reviewer for jira development, task description for personal, a github.com PR URL for pr_review, placeholder-safe variable names).
  • app/models/stage.rb — one step of a workflow. enum :stage_type has 8 values (implementation, pr_check, task, pr_review, jira_update, runbook_step, uat_test, local_test). There is no stage status column: progress is tracked on Workflow#status and in StageRun rows. enum :run_mode, { agent, message } (prefix run_) and the name / channel / auto_advance / wait_for_workflow columns are for runbook stages only. prompt is a per-stage text override that wins over any template, for any stage type. effective_template is the explicitly assigned prompt_template, else the first PromptTemplate of the same stage_type (lowest id) — there is no "active" flag.
  • app/models/stage_run.rb — one audit-log row per action taken on a stage (starts, completions, failures, merge/review/test outcomes, manual resume/rollback, runbook Next…). ACTIONS is the closed set of valid action values, enforced by an inclusion validation — add new values there, not ad hoc strings elsewhere.
  • app/models/prompt_template.rb — a reusable prompt body for a stage_type (same enum as Stage). PLACEHOLDERS lists the {TOKEN}s the UI offers; Prompts::Renderer is what actually substitutes them (including per-workflow custom variables). Prompts::Defaults holds the built-in fallback bodies for pr_review, jira_update, uat_test and local_test stages when no template exists (Prompts::StagePrompt applies them). has_many :stages, dependent: :nullify.
  • app/models/jira_sync.rb — one Jira query (project and/or parent ticket) for a project, with auto_sync and last-run bookkeeping.
  • app/models/bugsnag_sync.rb — one Bugsnag-project → Jira-project triage with thresholds and a ledger (JSON map of already-ticketed errors → Jira keys). Both have an auto scope.
  • app/models/application_record.rb, concerns/ — Rails defaults.

Conventions

  • status / stage_type / kind / run_mode / action are always closed, enumerable sets (Rails enum or the frozen ACTIONS array) — never a free-text column. Add new states to the existing enum/array rather than a parallel field. Enum integers are persisted: append, never renumber or reorder. Stage and PromptTemplate share the same stage_type mapping — change both together.
  • Every migration needs an explicit null: false, default: for anything that drives control flow (status, kind, position, processing, enable flags). The scheduler polls these columns, so an unexpected NULL breaks it silently. Follow recent migrations such as db/migrate/*_add_uat_testing.rb. Data-moving migrations should only touch narrowly selected rows.
  • Workflow#skill_list is the only place that parses the skills text column; if the format changes, update Prompts::Renderer's {SKILLS} substitution too (owned by ai-worker-orchestration).
  • New placeholders need both an entry in PromptTemplate::PLACEHOLDERS and a value in Prompts::Renderer; new StageRun::ACTIONS values must be added before any code logs them (an unknown action fails validation).
  • Describe model behaviour in specs, not by poking the real database. Write RSpec specs under spec/models/ (or spec/services/ for service objects) and run them with RAILS_ENV=test bundle exec rspec. Never run scratch scripts, bin/rails runner or console commands against the development database — it holds the user's real projects and workflows. Migrations on the development DB need a backup first and the user's say-so; for tests, RAILS_ENV=test loads db/schema.rb.