fix(WP-0014): pre-flight compilation fixes, Tailwind pipeline, and admin seed

A2 — Compilation fixes:
- Remove inline FK constraints from Schema.sql; IHP schema compiler cannot
  parse them. Add 1744329600-restore-fk-constraints.sql migration to restore
  referential integrity at the DB level.
- Rename `#label` → `#label_` throughout to avoid clash with Haskell built-in.
- Fix `hub.id == hid` UUID comparisons to use `toUUID hub.id`.
- Replace non-existent `setStatus`/`respondJson` calls with
  `renderJsonWithStatusCode` throughout Api controllers.
- Fix qualified package import for `cryptohash-sha256` in Auth.hs.
- Add `CanSelect (Text, Text)` instance in Helper.View.
- Refactor HSX inline lambdas to named helper functions in 100+ views
  (GHC cannot infer types for anonymous functions inside quasi-quoted HSX).
- Fix missing imports (IHP.QueryBuilder, IHP.Fetch, Web.Routes, Only, etc.)
  across helpers and controllers.
- Remove duplicate `diffUTCTime` definition in BottleneckDetector.
- Change `createEventForHub` return type from `IO ResponseReceived` to `IO ()`.
- Seed type-registry vocabulary via 1744502400-seed-type-registries.sql
  (moved from Schema.sql where IHP does not execute INSERT statements).

A3 — Tailwind build pipeline:
- Add `tailwindcss` to flake.nix native packages.
- Uncomment `tailwind.exec` process in devenv shell config.
- Add tailwind/tailwind.config.js (scans Web/View/**/*.hs).
- Add tailwind/app.css with @tailwind directives.

A4 — Admin user seed:
- Add 1744416000-seed-admin-user.sql: inserts admin@inter-hub.local
  with bcrypt-hashed password admin1234! (cost 10).
- Add .env.example documenting all required environment variables
  and default admin credentials.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 09:55:12 +00:00
parent ffd5fbb900
commit f1978c3888
147 changed files with 2710 additions and 2075 deletions

View File

@@ -0,0 +1,57 @@
-- Restore foreign key constraints removed from Schema.sql for IHP schema-compiler compatibility.
-- IHP infers FK relationships from column naming conventions; these ALTER TABLE statements
-- restore referential integrity enforcement at the database level.
-- Workplan: IHUB-WP-0014 (A2 — schema parser fixes)
-- Phase 1: Core hub/widget/event structure
ALTER TABLE widgets ADD FOREIGN KEY (hub_id) REFERENCES hubs(id);
ALTER TABLE widget_versions ADD FOREIGN KEY (widget_id) REFERENCES widgets(id);
ALTER TABLE interaction_events ADD FOREIGN KEY (widget_id) REFERENCES widgets(id);
ALTER TABLE annotation_threads ADD FOREIGN KEY (widget_id) REFERENCES widgets(id);
ALTER TABLE annotation_threads ADD FOREIGN KEY (created_by) REFERENCES users(id);
ALTER TABLE annotations ADD FOREIGN KEY (widget_id) REFERENCES widgets(id);
ALTER TABLE annotations ADD FOREIGN KEY (parent_id) REFERENCES annotations(id);
ALTER TABLE annotations ADD FOREIGN KEY (thread_id) REFERENCES annotation_threads(id);
ALTER TABLE annotations ADD FOREIGN KEY (created_by) REFERENCES users(id);
-- Phase 2: Requirement candidates and triage
ALTER TABLE requirement_candidates ADD FOREIGN KEY (source_widget_id) REFERENCES widgets(id);
ALTER TABLE requirement_candidates ADD FOREIGN KEY (source_thread_id) REFERENCES annotation_threads(id);
ALTER TABLE requirement_candidates ADD FOREIGN KEY (source_annotation_id) REFERENCES annotations(id);
ALTER TABLE requirement_candidates ADD FOREIGN KEY (created_by) REFERENCES users(id);
ALTER TABLE triage_states ADD FOREIGN KEY (candidate_id) REFERENCES requirement_candidates(id);
ALTER TABLE triage_states ADD FOREIGN KEY (changed_by) REFERENCES users(id);
ALTER TABLE reviewer_assignments ADD FOREIGN KEY (candidate_id) REFERENCES requirement_candidates(id);
ALTER TABLE reviewer_assignments ADD FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE reviewer_assignments ADD FOREIGN KEY (assigned_by) REFERENCES users(id);
ALTER TABLE requirement_candidates ADD FOREIGN KEY (source_candidate_id) REFERENCES requirement_candidates(id);
ALTER TABLE requirement_candidates ADD FOREIGN KEY (requirement_id) REFERENCES requirements(id);
-- Phase 3: Requirements and decisions
ALTER TABLE requirements ADD FOREIGN KEY (source_candidate_id) REFERENCES requirement_candidates(id);
ALTER TABLE requirements ADD FOREIGN KEY (created_by) REFERENCES users(id);
ALTER TABLE decision_records ADD FOREIGN KEY (requirement_id) REFERENCES requirements(id);
ALTER TABLE decision_records ADD FOREIGN KEY (candidate_id) REFERENCES requirement_candidates(id);
ALTER TABLE implementation_change_references ADD FOREIGN KEY (decision_id) REFERENCES decision_records(id);
ALTER TABLE policy_references ADD FOREIGN KEY (decision_id) REFERENCES decision_records(id);
-- Phase 4: Outcome observation
ALTER TABLE deployment_records ADD FOREIGN KEY (impl_ref_id) REFERENCES implementation_change_references(id);
ALTER TABLE deployment_records ADD FOREIGN KEY (decision_id) REFERENCES decision_records(id);
ALTER TABLE outcome_signals ADD FOREIGN KEY (widget_id) REFERENCES widgets(id);
ALTER TABLE outcome_signals ADD FOREIGN KEY (deployment_id) REFERENCES deployment_records(id);
-- Phase 5: Agent proposals
ALTER TABLE agent_review_records ADD FOREIGN KEY (proposal_id) REFERENCES agent_proposals(id);
ALTER TABLE confidence_annotations ADD FOREIGN KEY (proposal_id) REFERENCES agent_proposals(id);
-- Phase 9: API consumers and keys
ALTER TABLE api_keys ADD FOREIGN KEY (api_consumer_id) REFERENCES api_consumers(id);
ALTER TABLE webhook_subscriptions ADD FOREIGN KEY (api_consumer_id) REFERENCES api_consumers(id);
-- Phase 10: Widget patterns
ALTER TABLE pattern_adoptions ADD FOREIGN KEY (widget_pattern_id) REFERENCES widget_patterns(id);
-- Phase 12: Learning
ALTER TABLE institutional_knowledge_entries ADD FOREIGN KEY (hub_id) REFERENCES hubs(id);
ALTER TABLE institutional_knowledge_entries ADD FOREIGN KEY (decision_record_id) REFERENCES decision_records(id);

View File

@@ -0,0 +1,15 @@
-- Seed default admin user for initial local deployment.
-- Password: admin1234!
-- Hash generated with bcrypt cost 10 (compatible with IHP's authenticate @User).
-- IMPORTANT: Change this password immediately after first login via the profile settings.
-- Workplan: IHUB-WP-0014 (A4 — admin user seeding)
INSERT INTO users (id, email, password_hash, name, failed_login_attempts, created_at)
VALUES (
uuid_generate_v4(),
'admin@inter-hub.local',
'$2b$10$c3imjL8nLkR1TSbBifvR3eFzlCUurGPXsN7K5trDjmZL6Af3zLqH.',
'Admin',
0,
now()
);

View File

@@ -0,0 +1,54 @@
-- Seed framework-level type registry vocabulary (Phase 9 GAAF compliance).
-- Moved from Schema.sql — IHP's schema compiler only accepts DDL.
-- ON CONFLICT DO NOTHING makes this idempotent across re-runs.
-- Workplan: IHUB-WP-0014 (A2 — schema parser fixes)
INSERT INTO widget_type_registry (name, label, description) VALUES
('chart', 'Chart', 'Data visualisation chart widget'),
('form', 'Form', 'Data entry form widget'),
('table', 'Table', 'Tabular data display widget'),
('action', 'Action Control', 'Button, link, or trigger widget'),
('panel', 'Status Panel', 'Summary or status information panel'),
('workflow-step', 'Workflow Step', 'Single step in a multi-step workflow'),
('recommendation', 'Recommendation', 'AI or system recommendation block'),
('chat', 'Chat Region', 'Conversational interaction region'),
('diff', 'Diff / Review', 'Code diff or change review element')
ON CONFLICT (name) DO NOTHING;
INSERT INTO event_type_registry (name, label, description) VALUES
('viewed', 'Viewed', 'Widget was rendered and visible to the user'),
('focused', 'Focused', 'Widget received input focus'),
('clicked', 'Clicked', 'Widget was clicked or tapped'),
('submitted', 'Submitted', 'Form or action was submitted'),
('abandoned', 'Abandoned', 'User navigated away without completing'),
('retried', 'Retried', 'Action was retried after failure'),
('failed', 'Failed', 'Action or submission resulted in an error'),
('commented', 'Commented', 'User added a comment or annotation'),
('flagged_confusing', 'Flagged Confusing', 'User flagged the widget as confusing'),
('flagged_helpful', 'Flagged Helpful', 'User flagged the widget as helpful'),
('blocked_by_policy', 'Blocked by Policy', 'Action was blocked by a policy rule'),
('escalated', 'Escalated', 'Issue was escalated for review'),
('accepted_recommendation', 'Accepted Recommendation', 'User accepted an AI recommendation'),
('rejected_recommendation', 'Rejected Recommendation', 'User rejected an AI recommendation'),
('retracted', 'Retracted', 'Correction marker referencing original event in metadata')
ON CONFLICT (name) DO NOTHING;
INSERT INTO annotation_category_registry (name, label, description) VALUES
('friction', 'Friction', 'Interaction caused user effort or difficulty'),
('missing_capability', 'Missing Capability', 'Required feature or function is absent'),
('policy_conflict', 'Policy Conflict', 'Widget behaviour conflicts with a policy'),
('trust_deficit', 'Trust Deficit', 'User lacks confidence in the widget output'),
('accessibility', 'Accessibility', 'Accessibility or inclusive design concern'),
('workflow_bottleneck', 'Workflow Bottleneck', 'Widget creates a slowdown in the workflow'),
('documentation_gap', 'Documentation Gap', 'Missing or insufficient documentation'),
('product_opportunity', 'Product Opportunity', 'Observation suggesting a product improvement'),
('governance_concern', 'Governance Concern', 'Concern about governance, audit, or compliance')
ON CONFLICT (name) DO NOTHING;
INSERT INTO policy_scope_registry (name, label, description) VALUES
('internal', 'Internal', 'Applies to internal operators only'),
('org-wide', 'Organisation-Wide', 'Applies across the entire organisation'),
('external', 'External-Facing', 'Applies to externally visible surfaces'),
('regulatory', 'Regulatory', 'Driven by regulatory or compliance requirements'),
('security', 'Security', 'Security policy scope')
ON CONFLICT (name) DO NOTHING;