Skip to content

Add CoPlan::PlanType model#77

Merged
HamptonMakes merged 5 commits intomainfrom
plan-types
Apr 3, 2026
Merged

Add CoPlan::PlanType model#77
HamptonMakes merged 5 commits intomainfrom
plan-types

Conversation

@HamptonMakes
Copy link
Copy Markdown
Collaborator

@HamptonMakes HamptonMakes commented Apr 3, 2026

Summary

Adds a new CoPlan::PlanType model to categorize plans by type (e.g., RFC, Design Doc, ADR).

Changes

Model & Migration

  • coplan_plan_types table: UUID PK, name (unique, not null), description, default_tags (JSON), template_content, metadata (JSON), timestamps.
  • plan_type_id FK on coplan_plans (indexed, optional).
  • Data migration: Creates a "General" plan type and backfills all existing plans to it.
  • PlanType model: Validations (name presence + uniqueness), has_many :plans, dependent: :nullify, after_initialize defaults for JSON columns, ransackable_* methods.
  • Plan model: belongs_to :plan_type, optional: true, ransackable_attributes / ransackable_associations.

API

  • Create accepts optional plan_type_id (sanitized with .presence, invalid FK returns 422).
  • Responses include plan_type_id and plan_type_name.
  • Index uses .includes(:plan_type, :created_by_user) to avoid N+1.

Admin & Config

  • ActiveAdmin: Registration for PlanType; explicit filters on Plans admin to avoid ransack auto-filter issues.
  • Configuration: New seed_plan_types attribute (defaults to []).

Seeds

  • Seeds 4 plan types: General, RFC, Design Doc, ADR (idempotent).
  • Backfills untyped plans to General.

Tests

  • Model spec (7 examples): validations, defaults, associations, nullify-on-destroy.
  • API specs: create with valid/invalid plan_type_id.
  • Service specs: Plans::Create with and without plan_type_id.
  • All 519 non-system specs pass.

Verified

  • /admin/plans and /admin/plan_types tested in browser — both render correctly.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9634421a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

content: params[:content] || "",
user: current_user
user: current_user,
plan_type_id: params[:plan_type_id]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle invalid plan_type_id errors in plan creation

params[:plan_type_id] is passed directly into Plans::Create, where Plan.create! writes the FK. If a client sends a nonexistent ID, MySQL raises ActiveRecord::InvalidForeignKey, but this action only rescues ActiveRecord::RecordInvalid, so the API returns a 500 instead of a client-error response. This is a new failure mode introduced by accepting plan_type_id and will affect any caller that sends stale/typoed IDs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 58108af — added params[:plan_type_id].presence sanitization and rescue ActiveRecord::InvalidForeignKey returning 422. Also added API spec coverage for invalid plan_type_id.


create_table "coplan_users", id: { type: :string, limit: 36 }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.boolean "admin", default: false, null: false
t.string "avatar_url"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep schema changes backed by committed migrations

This commit adds new coplan_users columns in db/schema.rb (avatar_url, notification_preferences, team, title), but there is no migration in db/migrate or engine/db/migrate that creates them (repo-wide search only finds the new plan-types migration). That makes schema-load and migration-based setups diverge, which can cause environment drift and hard-to-diagnose deploy/test inconsistencies.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 58108af — reverted the unrelated coplan_users column additions (avatar_url, notification_preferences, team, title) from schema.rb. Only the plan_types migration changes remain.

HamptonMakes and others added 5 commits April 3, 2026 16:20
- Migration: coplan_plan_types table (UUID PK, name, description,
  default_tags, template_content, metadata) + plan_type_id FK on plans
- PlanType model with validations, after_initialize defaults, ransackable
- Plan belongs_to :plan_type (optional)
- Plans::Create service accepts plan_type_id
- API: plan create accepts plan_type_id, responses include plan_type fields
- Configuration: seed_plan_types attribute
- ActiveAdmin registration
- Factory and model specs

Amp-Thread-ID: https://ampcode.com/threads/T-019d54e9-adf1-746a-861d-2f2b14d1b882
Co-authored-by: Amp <amp@ampcode.com>
- Sanitize plan_type_id with .presence, rescue InvalidForeignKey → 422
- Add .includes(:plan_type, :created_by_user) to index to fix N+1
- Revert unrelated coplan_users schema.rb changes
- Remove non-functional default_tags from AA permit_params
- Add Create service specs for plan_type_id (with and without)
- Add API specs for valid/invalid plan_type_id on create
- Data migration creates 'General' plan type and sets it on all
  existing plans with NULL plan_type_id
- Seeds add General, RFC, Design Doc, ADR plan types (idempotent)
- Seeds backfill any untyped plans to General
- Add current_plan_version_id to Plan ransackable_attributes
- Add template_content to PlanType ransackable_attributes
- Explicitly declare filters on Plans admin to avoid auto-filter issues

Amp-Thread-ID: https://ampcode.com/threads/T-019d54e9-adf1-746a-861d-2f2b14d1b882
Co-authored-by: Amp <amp@ampcode.com>
@HamptonMakes HamptonMakes merged commit a5dd489 into main Apr 3, 2026
4 checks passed
@HamptonMakes HamptonMakes deleted the plan-types branch April 3, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant