Files
civitai__civitai/scripts/local-dev
Justin Maier 64cb925bd0 feat(contests): gate entries on allowed base models (#3425)
* feat(contests): gate model entries on allowed base models

Contest collections can now declare `metadata.baseModels`; a model entry
only qualifies if it has a live version on one of them. Empty/absent means
no gating, so existing contests are unaffected.

The date rule and the base-model rule are satisfied by a SINGLE version
predicate rather than two independent checks — otherwise a two-year-old
SDXL LoRA could qualify by pairing an old allowed-base-model version with
a throwaway version pushed during the submission window. The model block
also moved out of `if (metadata.submissionStartDate)` so base-model gating
still applies to windowless contests.

Moderators are not exempt, matching the neighbouring date/window checks
(the eligibility family) rather than `maxItemsPerUser` (an anti-spam quota
mods legitimately bypass when curating). A mod who wants an exception edits
the contest's allowed base models instead of side-stepping the rule.

* fix(contests): harden base-model gating and lock the where shape

Review follow-ups on the base-model gate:

- Guard the model-row date filter on submissionStartDate being set. It
  was unreachable with undefined today, but Prisma's lt is optional so
  undefined type-checks, and loosening the outer guard later would
  silently drop the filter and let every model through.
- Validate metadata.baseModels against the known base models. The value
  has to match ModelVersion.baseModel exactly; an unrecognized one like
  'FluxKrea' matched no version and locked the contest to zero entries
  while reporting a plausible-looking error.
- Spell out in the field description that with a submission window the
  same version must satisfy both rules.

Adds tests covering the where shape, most importantly that the
no-gating path is unchanged -- a live contest with accepted entries
depends on it -- and that the date and base-model conditions stay in
one modelVersions.none object.

Draft versions still qualify. Requiring Published would re-block the 69
in-window draft Krea 2 versions the preceding commits deliberately
unblocked, and entries pass through moderator review anyway.

* fix(contests): source base models from basemodel.constants

The gate read the legacy base-model.constants.ts, whose list stops
short of current ecosystems -- 'Krea 2' is absent from it, so the very
contest this was built for could not be configured, and the zod refine
would have rejected the value outright.

basemodel.constants.ts is the live source (95 importers vs 4, and it
carries a compatibility layer explicitly marked as the migration target
for the old file). Points the schema and the picker at it, moves the
two remaining importers over, and deletes the legacy file.

The picker now offers every base model rather than the non-hidden ones.
Hidden means "not offered on upload", which is a different question
from whether a contest can target it -- SD 3.5, SDXL Turbo, Kling and
Sora 2 are all populated and were unselectable. The field is
moderator-only.

* docs: drop references to the removed base-model.constants

Both docs described the legacy module as current. The plan doc keeps
its original snippets with a note, since rewriting a historical plan
would misrepresent what was proposed.
2026-07-28 13:48:04 -06:00
..