Spaces:
Running on Zero
Running on Zero
| const express = require('express'); | |
| const cors = require('cors'); | |
| const path = require('path'); | |
| const app = express(); | |
| const PORT = process.env.PORT || 7860; | |
| const AWS_API_BASE = process.env.API_URL || 'https://betaprecision.com/api/v1/chain-of-custody'; | |
| app.use(cors()); | |
| app.use(express.json({ limit: '20mb' })); | |
| app.use(express.static(path.join(__dirname, 'public'))); | |
| // Default Sample Dataset Fallback | |
| const FALLBACK_DEMO = { | |
| success: true, | |
| docName: "Master_Services_Agreement_Demo.pdf", | |
| clauses: [ | |
| { | |
| id: "clause-0", | |
| index: 1, | |
| heading: "ARTICLE 1. APPOINTMENT & SCOPE", | |
| text: "Provider shall perform professional technology consulting services as set forth in statements of work executed by both parties. All services will be performed in a professional and workmanlike manner.", | |
| matrix: [[0.12,0.08,-0.04],[0.08,0.15,-0.02],[-0.04,-0.02,0.18]], | |
| topCategory: "Warranty Disclaimer", | |
| topScore: 0.78, | |
| risk: { key: "risk-match", label: "Matches baseline" }, | |
| incomingEdge: null | |
| }, | |
| { | |
| id: "clause-1", | |
| index: 2, | |
| heading: "ARTICLE 2. UNLIMITED SPECIAL LIABILITY", | |
| text: "Notwithstanding any other provision herein, Provider's liability under this Agreement is completely uncapped, and Provider expressly waives all exclusions for incidental, indirect, punitive, or consequential damages.", | |
| matrix: [[-0.22,0.14,-0.18],[0.14,-0.28,0.12],[-0.18,0.12,-0.32]], | |
| topCategory: "Limitation of Liability", | |
| topScore: 0.32, | |
| risk: { key: "risk-diverge", label: "Diverges from baseline" }, | |
| incomingEdge: { from: "clause-0", to: "clause-1", fromIndex: 1, toIndex: 2, fidelity: 0.21, bures: 1.254, tension: 0.48, gamma: 0.14, status: "broken", breakReason: "Severe Liability Fracture (T=0.48)" } | |
| }, | |
| { | |
| id: "clause-2", | |
| index: 3, | |
| heading: "ARTICLE 3. SUDDEN UNILATERAL INDEMNIFICATION", | |
| text: "Provider shall defend, indemnify, and hold harmless Customer against any and all losses, damages, and legal costs arising from any claim, whether due to market fluctuations or Customer's contributory negligence.", | |
| matrix: [[-0.18,-0.08,0.22],[-0.08,0.19,-0.11],[0.22,-0.11,-0.25]], | |
| topCategory: "Indemnification", | |
| topScore: 0.41, | |
| risk: { key: "risk-diverge", label: "Diverges from baseline" }, | |
| incomingEdge: { from: "clause-1", to: "clause-2", fromIndex: 2, toIndex: 3, fidelity: 0.35, bures: 1.140, tension: 0.39, gamma: 0.22, status: "broken", breakReason: "Hostile Indemnity Shift" } | |
| } | |
| ], | |
| cocEdges: [ | |
| { from: "clause-0", to: "clause-1", fromIndex: 1, toIndex: 2, fidelity: 0.21, bures: 1.254, tension: 0.48, gamma: 0.14, status: "broken" }, | |
| { from: "clause-1", to: "clause-2", fromIndex: 2, toIndex: 3, fidelity: 0.35, bures: 1.140, tension: 0.39, gamma: 0.22, status: "broken" } | |
| ] | |
| }; | |
| // Route: Default CoC | |
| app.get('/api/coc/default', async (req, res) => { | |
| try { | |
| const response = await fetch(AWS_API_BASE, { | |
| method: 'GET', | |
| headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } | |
| }); | |
| if (!response.ok) throw new Error(`Backend returned HTTP ${response.status}`); | |
| const data = await response.json(); | |
| res.json(data); | |
| } catch (error) { | |
| console.warn('Backend unavailable, using fallback data:', error.message); | |
| res.json(FALLBACK_DEMO); | |
| } | |
| }); | |
| // Route: Analyze Contract | |
| app.post('/api/coc/analyze', async (req, res) => { | |
| try { | |
| const response = await fetch(`${AWS_API_BASE}/analyze`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, | |
| body: JSON.stringify(req.body) | |
| }); | |
| if (!response.ok) throw new Error(`Backend returned HTTP ${response.status}`); | |
| const data = await response.json(); | |
| res.json(data); | |
| } catch (error) { | |
| console.error('Analysis error:', error.message); | |
| res.status(500).json({ success: false, error: error.message }); | |
| } | |
| }); | |
| // Serve frontend SPA fallback | |
| app.get('*', (req, res) => { | |
| res.sendFile(path.join(__dirname, 'public', 'index.html')); | |
| }); | |
| app.listen(PORT, '0.0.0.0', () => { | |
| console.log(`⚡ Pure Node.js Server listening on port ${PORT}`); | |
| }); |