feat(event-sources): add displayed_columns config field (issue #833 slice 1/3) (#868)
* feat(event-sources): add displayed_columns config field (issue #833, slice 1a) First slice of issue #833 — custom columns for the event-search table. SOC admins will be able to choose which fields show up in the table per event source; both the SOC portal and the customer portal will render those columns. Storage decision: per EventSource row, JSON-typed, nullable. NULL/empty falls back to the frontend's hardcoded defaults so behaviour is unchanged for un-customised sources. This commit covers the model + Pydantic schema only — Alembic migration will be added in a follow-up commit on this branch. Slices 2 and 3 (SOC config UI, customer-portal render) ship as separate PRs. Changes: - universal_models.py: add `displayed_columns: Optional[List[dict]]` to EventSources via `Column(JSON, nullable=True)`. Imports gain `JSON` from sqlalchemy and `List` from typing. `update_from_model` now propagates the field. - siem/schema/event_sources.py: new `DisplayColumn` Pydantic model ({key, label, width?}). Wire `displayed_columns: Optional[List[DisplayColumn]]` into EventSourceCreate, EventSourceUpdate, EventSourceResponse. CRUD service uses `model_dump()` so the new field flows through without service-layer changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(event-sources): add upgrade and downgrade for displayed_columns in event_sources table * style: standardize string quotes and import order in add_display_event_source_columns migration --------- Co-authored-by: taylor_socfortress <taylor.walton@socfortress.co> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>