feat: unify onboarding fields with source column (#124) master
* feat(config): add HOSTING_MODE env var Adds HOSTING_MODE with 'saas' | 'selfhosted' options, defaulting to 'selfhosted'. SaaS mode will restrict platform field modifications; selfhosted gives full admin control over all onboarding fields. Part of: barazo-forum/barazo-workspace#71 * feat(schema): add source column to community_onboarding_fields Adds 'source' column with values 'platform' | 'admin' (default: 'admin'). Platform fields are seeded by Barazo; admin fields are created via the UI. Extensible for future 'plugin' source. Part of: barazo-forum/barazo-workspace#71 * feat(migration): backfill platform age field and user responses Seeds platform:age_confirmation field for existing initialized communities. Backfills user_onboarding_responses from user_preferences.declared_age so users who already declared their age aren't re-prompted. Part of: barazo-forum/barazo-workspace#71 * feat(setup): seed platform onboarding fields during initialization After community initialization, seeds platform:age_confirmation field with source='platform' and sortOrder=-1. Uses onConflictDoNothing for idempotent re-runs. Part of: barazo-forum/barazo-workspace#71 * feat(routes): add source field to admin onboarding endpoints with SaaS guards - GET /api/admin/onboarding-fields now returns { fields, hostingMode } - Each field includes source ('platform' | 'admin') in serialization - PUT and DELETE reject platform field modifications in SaaS mode (403) - Selfhosted mode allows full control over all fields Part of: barazo-forum/barazo-workspace#71 * refactor(routes): remove virtual field injection from user endpoints All onboarding fields (platform + admin) now come from the database. Removed SYSTEM_AGE_FIELD_ID constant, virtual age field injection in GET /api/onboarding/status, and system age submission separation in POST /api/onboarding/submit. All fields validated and stored uniformly. Part of: barazo-forum/barazo-workspace#71 * refactor(gate): simplify onboarding completeness check Removed virtual system age field injection and user_preferences lookup. The function now simply checks: are all mandatory DB fields answered? Platform and admin fields are treated uniformly. Part of: barazo-forum/barazo-workspace#71 * fix(migration): renumber migrations after rebase on main Renumber source column migration from 0001 to 0002 and backfill from 0002 to 0003, since main now has 0001_add_favicon_url.