Skip to content

feat(ship): add project types#360

Merged
dhamariT merged 15 commits into
hackclub:mainfrom
Nullskulls:feat/project-types
Jun 15, 2026
Merged

feat(ship): add project types#360
dhamariT merged 15 commits into
hackclub:mainfrom
Nullskulls:feat/project-types

Conversation

@Nullskulls

Copy link
Copy Markdown
Member

what's this do?

Add type checking via external API and a job to backfill already existing projects also changing how own projects are treated when shipped no longer hiding them though still disallowing reviews.

show it works

image image

ai?

Claude 🥀

Copilot AI review requested due to automatic review settings June 4, 2026 00:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR removes the project_categories field in favor of a single project_type, and introduces background/type inference + admin UI filtering to support the new workflow.

Changes:

  • Drop projects.project_categories from DB/schema and remove related model/view/test usages.
  • Add SwAi::ProjectTypeService + jobs to infer and backfill project_type.
  • Enhance the admin certification ship queue with type breakdown/filtering and “own project” UX.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
db/migrate/20260603180000_drop_project_categories_from_projects.rb Removes the project_categories column from projects.
db/schema.rb Reflects dropping project_categories and bumps schema version.
app/models/project.rb Removes validation tied to deleted project_categories.
app/services/sw_ai/project_type_service.rb Adds service that calls SW-AI to infer a project’s type.
config/initializers/sw_ai.rb Adds configuration for SW-AI URL + API key from credentials/env.
app/jobs/project/type_check_job.rb Enqueues type inference and persists project_type.
app/jobs/one_time/backfill_project_type_job.rb One-time enqueuer to backfill types for shipped projects.
app/models/post/ship_event.rb Triggers type-check job after ship creation if project_type is nil.
app/models/gorse/*_payload.rb Removes project_categories from Gorse categories/labels; uses project_type.
app/controllers/admin/certification/ships_controller.rb Adds type filtering, type counts, and own-project marking data.
app/policies/admin/certification/ship_policy.rb Changes reviewer scope and relaxes show? authorization.
app/views/admin/certification/ships/index.html.erb Adds type breakdown chips/filter UI + “Your Project/Ship” UI changes.
app/assets/stylesheets/pages/certification/ships/_index.scss Styles new type chips/tags.
app/assets/stylesheets/components/_action_button.scss Makes “disabled” action buttons non-clickable via pointer-events.
app/views/admin/projects/show.html.erb Removes admin display of removed project_categories.
app/views/admin/certification/ysws/*.erb Switches from categories display to project_type.
app/views/projects/show.html.erb Restricts “Add 15min (test)” button to members.
test/services/sw_ai/project_type_service_test.rb Adds tests for new SW-AI type service behavior.
test/models/gorse_payloads_test.rb Updates expectations to use project_type instead of categories.
test/models/project_test.rb, test/fixtures/projects.yml Removes schema comment references to project_categories.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/services/sw_ai/project_type_service.rb
Comment thread app/policies/admin/certification/ship_policy.rb Outdated
Comment thread app/policies/admin/certification/ship_policy.rb
Comment thread app/controllers/admin/certification/ships_controller.rb
Comment thread app/jobs/project/type_check_job.rb Outdated
Comment thread test/services/sw_ai/project_type_service_test.rb Outdated
Comment thread app/views/admin/certification/ships/index.html.erb
@Nullskulls Nullskulls force-pushed the feat/project-types branch from ff7e03e to aba8459 Compare June 4, 2026 00:43
@dhamariT

dhamariT commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Did you mean to add the test?

@Nullskulls

Copy link
Copy Markdown
Member Author

Yep! Want me to remove them?

@Nullskulls Nullskulls force-pushed the feat/project-types branch from 23285f0 to abefc5a Compare June 5, 2026 09:22
Merge identical &__label and &__filters label blocks into a single
grouped selector, removing 7 duplicate lines.
@Nullskulls Nullskulls force-pushed the feat/project-types branch from a6d8c8a to 12fa5c4 Compare June 5, 2026 16:21
@dhamariT

dhamariT commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

You're deleting the old project_categories collum.

Maybe you should Search the whole codebase for anywhere it's still used and make sure nothing's left. If something still uses it after it's deleteed, the app can break.

just lmk if's no longer being used.

@dhamariT

dhamariT commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Also, you wired up the new project "type" into Gorse, the recommendation system but type isn't supposed to touch recommendations (at least not for this PR), we're using it for it's own separate thing

@dhamariT dhamariT left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Read through the whole diff. The own-ships change is done right at the policy layer (show?/update? deny via not_own_project?, and available_for still excludes them from claiming), and the type plumbing into Gorse looks correct. One heads up for deploy: the migration drops project_categories for good, so once this runs the category data is gone. That's the point of the PR, just making sure it's deliberate. Left a few small notes inline, none of them blockers.

count = 0

scope.find_each do |project|
Project::TypeCheckJob.perform_later(project)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This enqueues one API call per shipped untyped project all at once, so the first run will hit the SW AI service with everything we have, throttled only by solid_queue worker concurrency. If the service rate limits, the 3-attempt retry will absorb some of it but some projects could end up unclassified until they ship again. Probably fine, just flagging it before someone runs the backfill.

result = SwAi::ProjectTypeService.new(project).call
return unless result.ok && result.type.present?

project.update_column(:project_type, result.type)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

update_column skips callbacks and paper_trail, so type changes won't show up in version history. Probably fine for a system-driven field, just noting it.

Comment thread app/assets/stylesheets/pages/certification/ships/_index.scss
Comment thread app/views/admin/certification/ysws/index.html.erb
Nullskulls and others added 3 commits June 11, 2026 23:40
Ship the code changes first (expand/contract). The destructive
remove_column migration is moved to a separate follow-up PR so the
column is only dropped after this deploys and nothing references it.
Restores the schema.rb column and model annotations in the meantime.
@dhamariT

Copy link
Copy Markdown
Collaborator

Heads up @Nullskulls — I pushed one commit to this branch ("defer project_categories column drop to follow-up"). It pulls the remove_column :projects, :project_categories migration out of this PR and restores the column in schema.rb plus the model annotations, so this PR now ships the code only and leaves the column in place. Nothing else changed.

The column drop now lives in #549 (draft), which should merge after this one is deployed. The idea is expand/contract: ship the code that stops using the column first, then drop the column once nothing reads it, so the destructive part isn't coupled to this deploy and can't take the queue down if it needs backing out.

Revert the commit if you'd rather keep it all in one PR.

dhamariT added a commit to dhamariT/stardance that referenced this pull request Jun 15, 2026
Follow-up to hackclub#360. That PR removes every code reference to
project_categories (validation, Gorse payloads, admin/project views)
but intentionally leaves the column in place. This migration drops the
now-unused column.

Must merge after hackclub#360 is deployed. Until hackclub#360 lands, main still reads
project_categories at runtime, so dropping the column before then would
break project saves.
Resolves the app/models/project.rb conflict from main's hardware_stage
feature. Keeps the hardware_stage validations from main and drops the
validate :validate_project_categories line (its method was already
removed on this branch; project_categories is going away in hackclub#549).
@dhamariT dhamariT added this pull request to the merge queue Jun 15, 2026
Merged via the queue into hackclub:main with commit d151815 Jun 15, 2026
7 checks passed
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.

3 participants