From c486b6ada9f8125e06ad4895971ed8564d2d0ed0 Mon Sep 17 00:00:00 2001 From: Shawn Price Date: Sun, 5 Oct 2025 17:38:47 -0700 Subject: [PATCH 1/8] Swap neutral to abstain and have LLM judge yes|no|abstain --- package.json | 4 +- pnpm-lock.yaml | 97 +++++++-- src/app/BillExplorer.tsx | 18 +- src/app/[id]/edit/page.tsx | 2 +- src/app/[id]/opengraph-image.tsx | 7 +- src/app/[id]/page.tsx | 21 +- src/app/bills/[id]/edit/page.tsx | 2 +- src/app/page.tsx | 4 +- src/app/types.ts | 2 +- src/components/BillCard.tsx | 16 +- src/components/BillDetail/BillAnalysis.tsx | 4 +- .../filter-section.component.tsx | 2 +- .../Judgement/judgement.component.tsx | 36 +--- src/components/OG | 4 +- src/components/OpenGraph/BillOgCard.tsx | 22 +-- src/components/OpenGraph/QuestionOgCard.tsx | 7 +- src/migrations/1.ts | 26 +++ src/models/Bill.ts | 4 +- src/prompt/summary-and-vote-prompt.ts | 26 ++- src/scripts/migrate.ts | 77 ++++++++ src/services/billApi.ts | 48 +++-- src/utils/billConverters.ts | 20 +- .../should-show-determination.test.ts | 185 +++--------------- .../should-show-determination.util.ts | 48 +---- src/utils/vote-display.ts | 35 ---- 25 files changed, 332 insertions(+), 385 deletions(-) create mode 100644 src/migrations/1.ts create mode 100644 src/scripts/migrate.ts delete mode 100644 src/utils/vote-display.ts diff --git a/package.json b/package.json index 2cf47d4..99d0eea 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "test:watch": "vitest", "test:ui": "vitest --ui", "test:coverage": "vitest run --coverage", - "prompt": "tsx src/scripts/copy-bill-prompt.ts" + "prompt": "tsx src/scripts/copy-bill-prompt.ts", + "migrate": "tsx src/scripts/migrate.ts" }, "dependencies": { "@auth/core": "0.34.2", @@ -79,6 +80,7 @@ "@types/react-dom": "19.1.9", "@vitest/ui": "^3.2.4", "daisyui": "^5.1.7", + "dotenv": "^17.2.3", "happy-dom": "^18.0.1", "husky": "^9.1.7", "tailwindcss": "^4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f899d5..fe11e7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@google/generative-ai': specifier: ^0.24.1 version: 0.24.1 + '@next/third-parties': + specifier: ^15.5.3 + version: 15.5.4(next@15.5.3(@babel/core@7.1.6)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) '@radix-ui/react-accordion': specifier: ^1.2.12 version: 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -101,6 +104,9 @@ importers: cmdk: specifier: ^1.1.1 version: 1.1.1(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + dayjs: + specifier: ^1.11.18 + version: 1.11.18 fast-xml-parser: specifier: ^5.2.5 version: 5.2.5 @@ -186,12 +192,21 @@ importers: daisyui: specifier: ^5.1.7 version: 5.1.12 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 happy-dom: specifier: ^18.0.1 version: 18.0.1 + husky: + specifier: ^9.1.7 + version: 9.1.7 tailwindcss: specifier: ^4 version: 4.1.13 + tsx: + specifier: ^4.20.5 + version: 4.20.6 tw-animate-css: specifier: ^1.3.8 version: 1.3.8 @@ -200,7 +215,7 @@ importers: version: 5.9.2 vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) packages: @@ -1535,6 +1550,12 @@ packages: cpu: [x64] os: [win32] + '@next/third-parties@15.5.4': + resolution: {integrity: sha512-l3T1M/EA32phPzZx+gkQAWOF3E5iAULL1nX4Ej0JZQOXaBwwJzb/rd2uefr5TAshJj/+HjjwmdFu7olXudvgVg==} + peerDependencies: + next: ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + '@nodelib/fs.stat@1.1.3': resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} engines: {node: '>= 6'} @@ -3781,6 +3802,9 @@ packages: date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dayjs@1.11.18: + resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3985,6 +4009,10 @@ packages: dotenv-expand@4.2.0: resolution: {integrity: sha512-pHWVt6L/YkqbBCMb1hG6e7oO0WdMhlapDIibl+BZ9PncVE3i+G77uvNr8GUxW2ItSituOK8QOYC9oOJjwWD94A==} + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + dotenv@6.0.0: resolution: {integrity: sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==} engines: {node: '>=6'} @@ -4643,6 +4671,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} @@ -4951,6 +4982,11 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -7661,6 +7697,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} deprecated: https://github.com/lydell/resolve-url#deprecated @@ -8326,6 +8365,9 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + third-party-capital@1.0.20: + resolution: {integrity: sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==} + throat@4.1.0: resolution: {integrity: sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==} @@ -8461,6 +8503,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + tty-browserify@0.0.0: resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} @@ -10926,6 +10973,12 @@ snapshots: '@next/swc-win32-x64-msvc@15.5.3': optional: true + '@next/third-parties@15.5.4(next@15.5.3(@babel/core@7.1.6)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)': + dependencies: + next: 15.5.3(@babel/core@7.1.6)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + third-party-capital: 1.0.20 + '@nodelib/fs.stat@1.1.3': {} '@panva/hkdf@1.2.1': {} @@ -11981,13 +12034,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0))': + '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0) + vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) '@vitest/pretty-format@3.2.4': dependencies: @@ -12018,7 +12071,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) '@vitest/utils@3.2.4': dependencies: @@ -13593,6 +13646,8 @@ snapshots: date-fns@4.1.0: {} + dayjs@1.11.18: {} + debug@2.6.9(supports-color@5.5.0): dependencies: ms: 2.0.0 @@ -13798,6 +13853,8 @@ snapshots: dotenv-expand@4.2.0: {} + dotenv@17.2.3: {} + dotenv@6.0.0: {} dunder-proto@1.0.1: @@ -14665,6 +14722,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + get-value@2.0.6: {} getpass@0.1.7: @@ -15066,6 +15127,8 @@ snapshots: transitivePeerDependencies: - supports-color + husky@9.1.7: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -18664,6 +18727,8 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve-url@0.2.1: {} resolve@1.1.7: {} @@ -19531,6 +19596,8 @@ snapshots: text-table@0.2.0: {} + third-party-capital@1.0.20: {} + throat@4.1.0: {} throat@5.0.0: {} @@ -19646,6 +19713,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.6: + dependencies: + esbuild: 0.25.9 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + tty-browserify@0.0.0: {} tunnel-agent@0.6.0: @@ -19948,13 +20022,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0): + vite-node@3.2.4(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0) + vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) transitivePeerDependencies: - '@types/node' - jiti @@ -19969,7 +20043,7 @@ snapshots: - tsx - yaml - vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0): + vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -19983,12 +20057,13 @@ snapshots: jiti: 2.5.1 lightningcss: 1.30.1 terser: 5.44.0 + tsx: 4.20.6 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.16)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)) + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -20006,8 +20081,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0) - vite-node: 3.2.4(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0) + vite: 7.1.5(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) + vite-node: 3.2.4(@types/node@20.19.16)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 diff --git a/src/app/BillExplorer.tsx b/src/app/BillExplorer.tsx index 47f4aad..9a47068 100644 --- a/src/app/BillExplorer.tsx +++ b/src/app/BillExplorer.tsx @@ -107,22 +107,14 @@ function BillExplorer({ bills }: BillExplorerProps) { // Filter bills const filteredBills = useMemo(() => { const filtered = bills.filter((bill) => { - const judgementParams: Parameters< - typeof shouldShowDetermination - >[0] = { - vote: bill.final_judgment, - isSocialIssue: bill.isSocialIssue, - tenetEvaluations: bill.tenet_evaluations, - }; - - const shouldDisplayDetermination = shouldShowDetermination(judgementParams); + const shouldDisplayDetermination = shouldShowDetermination(bill.final_judgment); const normalizedFinalJudgement: JudgementValue = - judgementParams.vote === "yes" || judgementParams.vote === "no" - ? judgementParams.vote - : "neutral"; + bill.final_judgment === "yes" || bill.final_judgment === "no" + ? bill.final_judgment + : "abstain"; const displayJudgement: JudgementValue = shouldDisplayDetermination ? normalizedFinalJudgement - : "neutral"; + : "abstain"; // Search if (filters.search.trim()) { diff --git a/src/app/[id]/edit/page.tsx b/src/app/[id]/edit/page.tsx index 496d35f..54022a9 100644 --- a/src/app/[id]/edit/page.tsx +++ b/src/app/[id]/edit/page.tsx @@ -73,7 +73,7 @@ export default async function EditBillPage({ params }: Params) {