Skip to content

Add CoPlan::Tag model with join table, API, and admin#79

Open
HamptonMakes wants to merge 1 commit intomainfrom
tag-model
Open

Add CoPlan::Tag model with join table, API, and admin#79
HamptonMakes wants to merge 1 commit intomainfrom
tag-model

Conversation

@HamptonMakes
Copy link
Copy Markdown
Collaborator

Summary

Introduces a first-class CoPlan::Tag model to replace/supplement the existing JSON tags array column on plans.

Changes

  • Migration: coplan_tags table (name + plans_count counter cache) and coplan_plan_tags join table with unique [plan_id, tag_id] constraint
  • Models: CoPlan::Tag and CoPlan::PlanTag with validations, counter cache, and ransackable methods
  • Plan association: has_many :plan_tags / has_many :structured_tags (existing JSON tags column preserved)
  • API: GET /api/v1/tags returning all tags sorted by frequency (plans_count desc)
  • ActiveAdmin: Tag registration with index/show views
  • Specs: Model specs for Tag and PlanTag, request specs for the tags API endpoint
  • Factories: tags.rb and plan_tags.rb

Notes

  • The existing JSON tags column on plans is kept for backward compatibility
  • Migration can be run on existing data without issues

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: 1f2c553176

ℹ️ 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".

module V1
class TagsController < BaseController
def index
tags = CoPlan::Tag.order(plans_count: :desc, name: :asc)
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 Restrict tag index to caller-visible plans

GET /api/v1/tags reads all tags via CoPlan::Tag.order(...) and returns global plans_count values without applying any plan visibility filter, so any authenticated token can discover tags attached to plans they should not be able to enumerate (including brainstorm-only content that Api::V1::PlansController#index intentionally hides). Scope the tags/counts to plans the current user can access before returning them.

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 — tags index now scopes to visible plans only (non-brainstorm + user's own brainstorm), matching PlansController#index visibility. Added specs for both the exclusion and inclusion cases. The plans_count returned is the visible count, not the global counter cache.

t.index ["tag_id"], name: "index_coplan_plan_tags_on_tag_id"
end

create_table "coplan_plan_types", id: { type: :string, limit: 36 }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
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 Remove schema entries that lack matching migrations

db/schema.rb in this commit introduces coplan_plan_types, coplan_plans.plan_type_id, and related foreign keys/columns, but there are no corresponding migration files in db/migrate or engine/db/migrate for those objects. This creates migration/schema drift (schema-load environments get structures migration-based environments never create), which can hide deployment and data-integrity issues; keep schema changes limited to objects created by migrations in the same commit.

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.

Resolved — after rebasing on main, coplan_plan_types and related columns now have matching migrations from the plan-types feature that landed on main. The schema.rb is regenerated from a clean database.

@HamptonMakes HamptonMakes force-pushed the tag-model branch 7 times, most recently from d362eae to 17c6bb4 Compare April 3, 2026 21:38
- Create coplan_tags table (name, plans_count counter cache) and
  coplan_plan_tags join table with unique constraint
- Add CoPlan::Tag and CoPlan::PlanTag models with validations
- Add has_many :plan_tags / :structured_tags to Plan model
  (keeps existing JSON tags column)
- Add GET /api/v1/tags endpoint sorted by frequency
- Add ActiveAdmin registration for tags
- Add factories and specs for models and API

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d54e9-adf1-746a-861d-3268c9113fa0
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