feat: pzmm conflict detection + content-type categorization

- mod_files manifest table populated at parse time
- POST /api/conflicts endpoint
- mod_types fingerprinting feeds derive_category
- DD filelist regex broadened to cover conflict-eligible exts
- media/maps/<*>/* excluded from manifest (per-mod namespaced,
  no conflict value, can be tens of MB per mod)

Plan: docs/plans/2026-05-04-pzmm-conflict-and-typing.md
This commit is contained in:
2026-05-04 15:22:35 +00:00
parent a15d35214e
commit b73325882e
9 changed files with 936 additions and 18 deletions

34
init/09_mod_files.sql Normal file
View File

@@ -0,0 +1,34 @@
-- pzmm-conflict-typing migration (Plan: docs/plans/2026-05-04-pzmm-conflict-and-typing.md)
--
-- Adds:
-- - mod_files: per-mod manifest of conflict-eligible asset files (lua/txt/xml/json/ini)
-- with sha1 fingerprint. Used by /api/conflicts to flag rel_paths claimed
-- by ≥2 mods with non-equal content.
-- - mod_parsed.mod_types: ordered tag list from detect_mod_types content fingerprinting
-- (Maps, Vehicles, Weapons, Traits, …). Consumed by derive_category.
-- - mod_parsed.files_manifest_built: graceful-degradation flag. False until the
-- worker has run the single-pass media/ walk that produces both the
-- manifest rows and mod_types. Old cached rows stay false until they
-- organically re-parse.
--
-- Backfill strategy: organic only — time_updated bumps trigger re-parse, which
-- now also runs the manifest walk. /api/conflicts surfaces missing_manifests so
-- the frontend can communicate gaps without lying.
CREATE TABLE IF NOT EXISTS mod_files (
workshop_id TEXT NOT NULL,
mod_id TEXT NOT NULL,
rel_path TEXT NOT NULL,
sha1 TEXT NOT NULL,
size_bytes INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (workshop_id, mod_id, rel_path),
FOREIGN KEY (workshop_id, mod_id)
REFERENCES mod_parsed (workshop_id, mod_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS mod_files_rel_path_idx ON mod_files (rel_path);
CREATE INDEX IF NOT EXISTS mod_files_mod_idx ON mod_files (workshop_id, mod_id);
ALTER TABLE mod_parsed
ADD COLUMN IF NOT EXISTS mod_types TEXT[] NOT NULL DEFAULT '{}',
ADD COLUMN IF NOT EXISTS files_manifest_built BOOLEAN NOT NULL DEFAULT FALSE;