Compare commits
	
		
			2 Commits
		
	
	
		
			39b1e97072
			...
			66d14247cf
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 66d14247cf | |||
| bce5b1dcec | 
							
								
								
									
										34
									
								
								Elecciones-Web/frontend/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Elecciones-Web/frontend/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | # --- Etapa 1: Build (Construcción) --- | ||||||
|  | # Usamos una imagen de Node.js para instalar dependencias y construir la aplicación de React. | ||||||
|  | FROM node:20-alpine AS build | ||||||
|  |  | ||||||
|  | # Establecemos el directorio de trabajo dentro del contenedor. | ||||||
|  | WORKDIR /app | ||||||
|  |  | ||||||
|  | # Copiamos los archivos de manifiesto del proyecto. | ||||||
|  | COPY package.json ./ | ||||||
|  | COPY package-lock.json ./ | ||||||
|  |  | ||||||
|  | # Instalamos las dependencias. | ||||||
|  | RUN npm install | ||||||
|  |  | ||||||
|  | # Copiamos el resto del código fuente de la aplicación. | ||||||
|  | COPY . . | ||||||
|  |  | ||||||
|  | # Ejecutamos el script de construcción de Vite para generar los archivos estáticos. | ||||||
|  | RUN npm run build | ||||||
|  |  | ||||||
|  | # --- Etapa 2: Serve (Servir) --- | ||||||
|  | # Usamos una imagen de Nginx, que es un servidor web muy ligero y eficiente. | ||||||
|  | # Es ideal para servir archivos estáticos (HTML, CSS, JS). | ||||||
|  | FROM nginx:1.25-alpine | ||||||
|  |  | ||||||
|  | # Copiamos los archivos de producción construidos en la etapa anterior | ||||||
|  | # al directorio por defecto donde Nginx sirve los archivos. | ||||||
|  | COPY --from=build /app/dist /usr/share/nginx/html | ||||||
|  |  | ||||||
|  | # Exponemos el puerto 80 (el puerto por defecto de Nginx). | ||||||
|  | EXPOSE 80 | ||||||
|  |  | ||||||
|  | # El comando por defecto de la imagen de Nginx ya es iniciar el servidor, | ||||||
|  | # así que no necesitamos un CMD o ENTRYPOINT. | ||||||
							
								
								
									
										752
									
								
								Elecciones-Web/frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										752
									
								
								Elecciones-Web/frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -9,11 +9,14 @@ | |||||||
|       "version": "0.0.0", |       "version": "0.0.0", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "axios": "^1.11.0", |         "axios": "^1.11.0", | ||||||
|  |         "d3": "^7.9.0", | ||||||
|         "react": "^19.1.1", |         "react": "^19.1.1", | ||||||
|         "react-dom": "^19.1.1" |         "react-dom": "^19.1.1" | ||||||
|       }, |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@eslint/js": "^9.33.0", |         "@eslint/js": "^9.33.0", | ||||||
|  |         "@types/d3": "^7.4.3", | ||||||
|  |         "@types/geojson": "^7946.0.16", | ||||||
|         "@types/react": "^19.1.10", |         "@types/react": "^19.1.10", | ||||||
|         "@types/react-dom": "^19.1.7", |         "@types/react-dom": "^19.1.7", | ||||||
|         "@vitejs/plugin-react": "^5.0.0", |         "@vitejs/plugin-react": "^5.0.0", | ||||||
| @@ -1393,6 +1396,290 @@ | |||||||
|         "@babel/types": "^7.28.2" |         "@babel/types": "^7.28.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@types/d3": { | ||||||
|  |       "version": "7.4.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", | ||||||
|  |       "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-array": "*", | ||||||
|  |         "@types/d3-axis": "*", | ||||||
|  |         "@types/d3-brush": "*", | ||||||
|  |         "@types/d3-chord": "*", | ||||||
|  |         "@types/d3-color": "*", | ||||||
|  |         "@types/d3-contour": "*", | ||||||
|  |         "@types/d3-delaunay": "*", | ||||||
|  |         "@types/d3-dispatch": "*", | ||||||
|  |         "@types/d3-drag": "*", | ||||||
|  |         "@types/d3-dsv": "*", | ||||||
|  |         "@types/d3-ease": "*", | ||||||
|  |         "@types/d3-fetch": "*", | ||||||
|  |         "@types/d3-force": "*", | ||||||
|  |         "@types/d3-format": "*", | ||||||
|  |         "@types/d3-geo": "*", | ||||||
|  |         "@types/d3-hierarchy": "*", | ||||||
|  |         "@types/d3-interpolate": "*", | ||||||
|  |         "@types/d3-path": "*", | ||||||
|  |         "@types/d3-polygon": "*", | ||||||
|  |         "@types/d3-quadtree": "*", | ||||||
|  |         "@types/d3-random": "*", | ||||||
|  |         "@types/d3-scale": "*", | ||||||
|  |         "@types/d3-scale-chromatic": "*", | ||||||
|  |         "@types/d3-selection": "*", | ||||||
|  |         "@types/d3-shape": "*", | ||||||
|  |         "@types/d3-time": "*", | ||||||
|  |         "@types/d3-time-format": "*", | ||||||
|  |         "@types/d3-timer": "*", | ||||||
|  |         "@types/d3-transition": "*", | ||||||
|  |         "@types/d3-zoom": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-array": { | ||||||
|  |       "version": "3.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", | ||||||
|  |       "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-axis": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", | ||||||
|  |       "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-selection": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-brush": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", | ||||||
|  |       "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-selection": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-chord": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", | ||||||
|  |       "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-color": { | ||||||
|  |       "version": "3.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", | ||||||
|  |       "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-contour": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", | ||||||
|  |       "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-array": "*", | ||||||
|  |         "@types/geojson": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-delaunay": { | ||||||
|  |       "version": "6.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", | ||||||
|  |       "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-dispatch": { | ||||||
|  |       "version": "3.0.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", | ||||||
|  |       "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-drag": { | ||||||
|  |       "version": "3.0.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", | ||||||
|  |       "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-selection": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-dsv": { | ||||||
|  |       "version": "3.0.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", | ||||||
|  |       "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-ease": { | ||||||
|  |       "version": "3.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", | ||||||
|  |       "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-fetch": { | ||||||
|  |       "version": "3.0.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", | ||||||
|  |       "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-dsv": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-force": { | ||||||
|  |       "version": "3.0.10", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", | ||||||
|  |       "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-format": { | ||||||
|  |       "version": "3.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", | ||||||
|  |       "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-geo": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/geojson": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-hierarchy": { | ||||||
|  |       "version": "3.1.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", | ||||||
|  |       "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-interpolate": { | ||||||
|  |       "version": "3.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", | ||||||
|  |       "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-color": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-path": { | ||||||
|  |       "version": "3.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", | ||||||
|  |       "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-polygon": { | ||||||
|  |       "version": "3.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", | ||||||
|  |       "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-quadtree": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", | ||||||
|  |       "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-random": { | ||||||
|  |       "version": "3.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", | ||||||
|  |       "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-scale": { | ||||||
|  |       "version": "4.0.9", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", | ||||||
|  |       "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-time": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-scale-chromatic": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-selection": { | ||||||
|  |       "version": "3.0.11", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", | ||||||
|  |       "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-shape": { | ||||||
|  |       "version": "3.1.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", | ||||||
|  |       "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-path": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-time": { | ||||||
|  |       "version": "3.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", | ||||||
|  |       "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-time-format": { | ||||||
|  |       "version": "4.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", | ||||||
|  |       "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-timer": { | ||||||
|  |       "version": "3.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", | ||||||
|  |       "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-transition": { | ||||||
|  |       "version": "3.0.9", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", | ||||||
|  |       "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-selection": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/d3-zoom": { | ||||||
|  |       "version": "3.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", | ||||||
|  |       "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/d3-interpolate": "*", | ||||||
|  |         "@types/d3-selection": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/@types/estree": { |     "node_modules/@types/estree": { | ||||||
|       "version": "1.0.8", |       "version": "1.0.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", |       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", | ||||||
| @@ -1400,6 +1687,13 @@ | |||||||
|       "dev": true, |       "dev": true, | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@types/geojson": { | ||||||
|  |       "version": "7946.0.16", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", | ||||||
|  |       "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/@types/json-schema": { |     "node_modules/@types/json-schema": { | ||||||
|       "version": "7.0.15", |       "version": "7.0.15", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", |       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", | ||||||
| @@ -1956,6 +2250,15 @@ | |||||||
|         "node": ">= 0.8" |         "node": ">= 0.8" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/commander": { | ||||||
|  |       "version": "7.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", | ||||||
|  |       "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/concat-map": { |     "node_modules/concat-map": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
| @@ -1992,6 +2295,407 @@ | |||||||
|       "dev": true, |       "dev": true, | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/d3": { | ||||||
|  |       "version": "7.9.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", | ||||||
|  |       "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-array": "3", | ||||||
|  |         "d3-axis": "3", | ||||||
|  |         "d3-brush": "3", | ||||||
|  |         "d3-chord": "3", | ||||||
|  |         "d3-color": "3", | ||||||
|  |         "d3-contour": "4", | ||||||
|  |         "d3-delaunay": "6", | ||||||
|  |         "d3-dispatch": "3", | ||||||
|  |         "d3-drag": "3", | ||||||
|  |         "d3-dsv": "3", | ||||||
|  |         "d3-ease": "3", | ||||||
|  |         "d3-fetch": "3", | ||||||
|  |         "d3-force": "3", | ||||||
|  |         "d3-format": "3", | ||||||
|  |         "d3-geo": "3", | ||||||
|  |         "d3-hierarchy": "3", | ||||||
|  |         "d3-interpolate": "3", | ||||||
|  |         "d3-path": "3", | ||||||
|  |         "d3-polygon": "3", | ||||||
|  |         "d3-quadtree": "3", | ||||||
|  |         "d3-random": "3", | ||||||
|  |         "d3-scale": "4", | ||||||
|  |         "d3-scale-chromatic": "3", | ||||||
|  |         "d3-selection": "3", | ||||||
|  |         "d3-shape": "3", | ||||||
|  |         "d3-time": "3", | ||||||
|  |         "d3-time-format": "4", | ||||||
|  |         "d3-timer": "3", | ||||||
|  |         "d3-transition": "3", | ||||||
|  |         "d3-zoom": "3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-array": { | ||||||
|  |       "version": "3.2.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", | ||||||
|  |       "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "internmap": "1 - 2" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-axis": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-brush": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-dispatch": "1 - 3", | ||||||
|  |         "d3-drag": "2 - 3", | ||||||
|  |         "d3-interpolate": "1 - 3", | ||||||
|  |         "d3-selection": "3", | ||||||
|  |         "d3-transition": "3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-chord": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-path": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-color": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-contour": { | ||||||
|  |       "version": "4.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", | ||||||
|  |       "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-array": "^3.2.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-delaunay": { | ||||||
|  |       "version": "6.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", | ||||||
|  |       "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "delaunator": "5" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-dispatch": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-drag": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-dispatch": "1 - 3", | ||||||
|  |         "d3-selection": "3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-dsv": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "commander": "7", | ||||||
|  |         "iconv-lite": "0.6", | ||||||
|  |         "rw": "1" | ||||||
|  |       }, | ||||||
|  |       "bin": { | ||||||
|  |         "csv2json": "bin/dsv2json.js", | ||||||
|  |         "csv2tsv": "bin/dsv2dsv.js", | ||||||
|  |         "dsv2dsv": "bin/dsv2dsv.js", | ||||||
|  |         "dsv2json": "bin/dsv2json.js", | ||||||
|  |         "json2csv": "bin/json2dsv.js", | ||||||
|  |         "json2dsv": "bin/json2dsv.js", | ||||||
|  |         "json2tsv": "bin/json2dsv.js", | ||||||
|  |         "tsv2csv": "bin/dsv2dsv.js", | ||||||
|  |         "tsv2json": "bin/dsv2json.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-ease": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", | ||||||
|  |       "license": "BSD-3-Clause", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-fetch": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-dsv": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-force": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-dispatch": "1 - 3", | ||||||
|  |         "d3-quadtree": "1 - 3", | ||||||
|  |         "d3-timer": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-format": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-geo": { | ||||||
|  |       "version": "3.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", | ||||||
|  |       "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-array": "2.5.0 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-hierarchy": { | ||||||
|  |       "version": "3.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", | ||||||
|  |       "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-interpolate": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-color": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-path": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-polygon": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-quadtree": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-random": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-scale": { | ||||||
|  |       "version": "4.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", | ||||||
|  |       "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-array": "2.10.0 - 3", | ||||||
|  |         "d3-format": "1 - 3", | ||||||
|  |         "d3-interpolate": "1.2.0 - 3", | ||||||
|  |         "d3-time": "2.1.1 - 3", | ||||||
|  |         "d3-time-format": "2 - 4" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-scale-chromatic": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-color": "1 - 3", | ||||||
|  |         "d3-interpolate": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-selection": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-shape": { | ||||||
|  |       "version": "3.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", | ||||||
|  |       "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-path": "^3.1.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-time": { | ||||||
|  |       "version": "3.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", | ||||||
|  |       "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-array": "2 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-time-format": { | ||||||
|  |       "version": "4.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", | ||||||
|  |       "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-time": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-timer": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-transition": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-color": "1 - 3", | ||||||
|  |         "d3-dispatch": "1 - 3", | ||||||
|  |         "d3-ease": "1 - 3", | ||||||
|  |         "d3-interpolate": "1 - 3", | ||||||
|  |         "d3-timer": "1 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "d3-selection": "2 - 3" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/d3-zoom": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "d3-dispatch": "1 - 3", | ||||||
|  |         "d3-drag": "2 - 3", | ||||||
|  |         "d3-interpolate": "1 - 3", | ||||||
|  |         "d3-selection": "2 - 3", | ||||||
|  |         "d3-transition": "2 - 3" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/debug": { |     "node_modules/debug": { | ||||||
|       "version": "4.4.1", |       "version": "4.4.1", | ||||||
|       "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", |       "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", | ||||||
| @@ -2017,6 +2721,15 @@ | |||||||
|       "dev": true, |       "dev": true, | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/delaunator": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "robust-predicates": "^3.0.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/delayed-stream": { |     "node_modules/delayed-stream": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||||||
| @@ -2661,6 +3374,18 @@ | |||||||
|         "node": ">= 0.4" |         "node": ">= 0.4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/iconv-lite": { | ||||||
|  |       "version": "0.6.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", | ||||||
|  |       "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "safer-buffer": ">= 2.1.2 < 3.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.10.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/ignore": { |     "node_modules/ignore": { | ||||||
|       "version": "5.3.2", |       "version": "5.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", |       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", | ||||||
| @@ -2698,6 +3423,15 @@ | |||||||
|         "node": ">=0.8.19" |         "node": ">=0.8.19" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/internmap": { | ||||||
|  |       "version": "2.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", | ||||||
|  |       "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/is-extglob": { |     "node_modules/is-extglob": { | ||||||
|       "version": "2.1.1", |       "version": "2.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", |       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", | ||||||
| @@ -3200,6 +3934,12 @@ | |||||||
|         "node": ">=0.10.0" |         "node": ">=0.10.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/robust-predicates": { | ||||||
|  |       "version": "3.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", | ||||||
|  |       "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", | ||||||
|  |       "license": "Unlicense" | ||||||
|  |     }, | ||||||
|     "node_modules/rollup": { |     "node_modules/rollup": { | ||||||
|       "version": "4.46.2", |       "version": "4.46.2", | ||||||
|       "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", |       "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", | ||||||
| @@ -3264,6 +4004,18 @@ | |||||||
|         "queue-microtask": "^1.2.2" |         "queue-microtask": "^1.2.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/rw": { | ||||||
|  |       "version": "1.3.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", | ||||||
|  |       "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", | ||||||
|  |       "license": "BSD-3-Clause" | ||||||
|  |     }, | ||||||
|  |     "node_modules/safer-buffer": { | ||||||
|  |       "version": "2.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", | ||||||
|  |       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/scheduler": { |     "node_modules/scheduler": { | ||||||
|       "version": "0.26.0", |       "version": "0.26.0", | ||||||
|       "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", |       "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", | ||||||
|   | |||||||
| @@ -11,11 +11,14 @@ | |||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "axios": "^1.11.0", |     "axios": "^1.11.0", | ||||||
|  |     "d3": "^7.9.0", | ||||||
|     "react": "^19.1.1", |     "react": "^19.1.1", | ||||||
|     "react-dom": "^19.1.1" |     "react-dom": "^19.1.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@eslint/js": "^9.33.0", |     "@eslint/js": "^9.33.0", | ||||||
|  |     "@types/d3": "^7.4.3", | ||||||
|  |     "@types/geojson": "^7946.0.16", | ||||||
|     "@types/react": "^19.1.10", |     "@types/react": "^19.1.10", | ||||||
|     "@types/react-dom": "^19.1.7", |     "@types/react-dom": "^19.1.7", | ||||||
|     "@vitejs/plugin-react": "^5.0.0", |     "@vitejs/plugin-react": "^5.0.0", | ||||||
|   | |||||||
							
								
								
									
										150
									
								
								Elecciones-Web/frontend/public/buenos-aires-municipios.geojson
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								Elecciones-Web/frontend/public/buenos-aires-municipios.geojson
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										145
									
								
								Elecciones-Web/frontend/public/municipioIdMap.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Elecciones-Web/frontend/public/municipioIdMap.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | |||||||
|  | { | ||||||
|  |   "100": "100", | ||||||
|  |   "101": "101", | ||||||
|  |   "102": "102", | ||||||
|  |   "103": "103", | ||||||
|  |   "104": "104", | ||||||
|  |   "105": "105", | ||||||
|  |   "106": "106", | ||||||
|  |   "107": "107", | ||||||
|  |   "108": "108", | ||||||
|  |   "109": "109", | ||||||
|  |   "110": "110", | ||||||
|  |   "111": "111", | ||||||
|  |   "113": "113", | ||||||
|  |   "114": "114", | ||||||
|  |   "115": "115", | ||||||
|  |   "116": "116", | ||||||
|  |   "117": "117", | ||||||
|  |   "118": "118", | ||||||
|  |   "119": "119", | ||||||
|  |   "120": "120", | ||||||
|  |   "121": "121", | ||||||
|  |   "122": "122", | ||||||
|  |   "123": "123", | ||||||
|  |   "124": "124", | ||||||
|  |   "125": "125", | ||||||
|  |   "126": "126", | ||||||
|  |   "127": "127", | ||||||
|  |   "128": "128", | ||||||
|  |   "129": "129", | ||||||
|  |   "130": "130", | ||||||
|  |   "131": "131", | ||||||
|  |   "132": "132", | ||||||
|  |   "133": "133", | ||||||
|  |   "134": "134", | ||||||
|  |   "135": "135", | ||||||
|  |   "136": "136", | ||||||
|  |   "137": "137", | ||||||
|  |   "309": "309", | ||||||
|  |   "314": "314", | ||||||
|  |   "338": "338", | ||||||
|  |   "357": "357", | ||||||
|  |   "387": "387", | ||||||
|  |   "396": "396", | ||||||
|  |   "398": "398", | ||||||
|  |   "399": "399", | ||||||
|  |   "045": "045", | ||||||
|  |   "055": "055", | ||||||
|  |   "070": "070", | ||||||
|  |   "030": "030", | ||||||
|  |   "074": "074", | ||||||
|  |   "003": "003", | ||||||
|  |   "086": "086", | ||||||
|  |   "082": "082", | ||||||
|  |   "063": "063", | ||||||
|  |   "006": "006", | ||||||
|  |   "047": "047", | ||||||
|  |   "084": "084", | ||||||
|  |   "026": "026", | ||||||
|  |   "025": "025", | ||||||
|  |   "007": "007", | ||||||
|  |   "033": "033", | ||||||
|  |   "076": "076", | ||||||
|  |   "054": "054", | ||||||
|  |   "072": "072", | ||||||
|  |   "012": "012", | ||||||
|  |   "004": "004", | ||||||
|  |   "077": "077", | ||||||
|  |   "087": "087", | ||||||
|  |   "098": "098", | ||||||
|  |   "015": "015", | ||||||
|  |   "080": "080", | ||||||
|  |   "046": "046", | ||||||
|  |   "038": "038", | ||||||
|  |   "032": "032", | ||||||
|  |   "014": "014", | ||||||
|  |   "064": "064", | ||||||
|  |   "083": "083", | ||||||
|  |   "049": "049", | ||||||
|  |   "058": "058", | ||||||
|  |   "023": "023", | ||||||
|  |   "060": "060", | ||||||
|  |   "018": "018", | ||||||
|  |   "042": "042", | ||||||
|  |   "062": "062", | ||||||
|  |   "066": "066", | ||||||
|  |   "041": "041", | ||||||
|  |   "053": "053", | ||||||
|  |   "057": "057", | ||||||
|  |   "001": "001", | ||||||
|  |   "005": "005", | ||||||
|  |   "002": "002", | ||||||
|  |   "031": "031", | ||||||
|  |   "008": "008", | ||||||
|  |   "009": "009", | ||||||
|  |   "013": "013", | ||||||
|  |   "010": "010", | ||||||
|  |   "011": "011", | ||||||
|  |   "019": "019", | ||||||
|  |   "017": "017", | ||||||
|  |   "097": "097", | ||||||
|  |   "020": "020", | ||||||
|  |   "016": "016", | ||||||
|  |   "037": "037", | ||||||
|  |   "021": "021", | ||||||
|  |   "027": "027", | ||||||
|  |   "022": "022", | ||||||
|  |   "036": "036", | ||||||
|  |   "029": "029", | ||||||
|  |   "028": "028", | ||||||
|  |   "035": "035", | ||||||
|  |   "056": "056", | ||||||
|  |   "044": "044", | ||||||
|  |   "034": "034", | ||||||
|  |   "040": "040", | ||||||
|  |   "039": "039", | ||||||
|  |   "043": "043", | ||||||
|  |   "051": "051", | ||||||
|  |   "052": "052", | ||||||
|  |   "059": "059", | ||||||
|  |   "065": "065", | ||||||
|  |   "061": "061", | ||||||
|  |   "024": "024", | ||||||
|  |   "068": "068", | ||||||
|  |   "050": "050", | ||||||
|  |   "078": "078", | ||||||
|  |   "079": "079", | ||||||
|  |   "067": "067", | ||||||
|  |   "096": "096", | ||||||
|  |   "099": "099", | ||||||
|  |   "075": "075", | ||||||
|  |   "081": "081", | ||||||
|  |   "069": "069", | ||||||
|  |   "073": "073", | ||||||
|  |   "089": "089", | ||||||
|  |   "090": "090", | ||||||
|  |   "085": "085", | ||||||
|  |   "088": "088", | ||||||
|  |   "091": "091", | ||||||
|  |   "093": "093", | ||||||
|  |   "071": "071", | ||||||
|  |   "095": "095", | ||||||
|  |   "092": "092", | ||||||
|  |   "094": "094" | ||||||
|  | } | ||||||
| @@ -40,3 +40,7 @@ | |||||||
| .read-the-docs { | .read-the-docs { | ||||||
|   color: #888; |   color: #888; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | section { | ||||||
|  |   margin-bottom: 2rem; | ||||||
|  | } | ||||||
| @@ -1,28 +1,100 @@ | |||||||
| // src/App.tsx | // src/App.tsx | ||||||
| import { useState } from 'react'; | import { useState, useEffect } from 'react'; | ||||||
| import { MunicipioWidget } from './components/MunicipioWidget'; | import { MunicipioWidget } from './components/MunicipioWidget'; | ||||||
| import { MunicipioSelector } from './components/MunicipioSelector'; | import { MunicipioSelector } from './components/MunicipioSelector'; | ||||||
|  | import { getMunicipios, type MunicipioSimple } from './services/api'; | ||||||
| import './App.css'; | import './App.css'; | ||||||
|  | import { ResumenProvincialWidget } from './components/ResumenProvincialWidget'; | ||||||
|  | import { BancasWidget } from './components/BancasWidget'; | ||||||
|  | import { TelegramasView } from './components/TelegramasView'; | ||||||
|  | import { MapaD3Widget } from './components/MapaD3Widget'; | ||||||
|  |  | ||||||
| function App() { | function App() { | ||||||
|   const [selectedMunicipioId, setSelectedMunicipioId] = useState<string | null>(null); |   const [selectedMunicipioId, setSelectedMunicipioId] = useState<string | null>(null); | ||||||
|  |   const [listaMunicipios, setListaMunicipios] = useState<MunicipioSimple[]>([]); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     getMunicipios() | ||||||
|  |       .then(setListaMunicipios) | ||||||
|  |       .catch(err => console.error("Error al cargar la lista de municipios", err)) | ||||||
|  |       .finally(() => setLoading(false)); | ||||||
|  |   }, []); | ||||||
|  |  | ||||||
|  |   if (loading) return <h1>Cargando datos iniciales...</h1>; | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <h1>Elecciones 2025 - Resultados en Vivo</h1> |       <h1>Elecciones 2025 - Resultados en Vivo</h1> | ||||||
|        |       <section> | ||||||
|       {/* Aquí podrías poner el widget del Resumen Provincial */} |         <ResumenProvincialWidget distritoId="02" /> | ||||||
|  |       </section> | ||||||
|  |  | ||||||
|       <hr /> |       <hr /> | ||||||
|        |        | ||||||
|  |       <section style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '20px' }}> | ||||||
|  |         <div> | ||||||
|  |           <h2>Mapa de Resultados</h2> | ||||||
|  |           <MapaD3Widget | ||||||
|  |             municipios={listaMunicipios}  | ||||||
|  |             onMunicipioClick={setSelectedMunicipioId}  | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|           <h2>Consulta por Municipio</h2> |           <h2>Consulta por Municipio</h2> | ||||||
|       <MunicipioSelector onMunicipioChange={setSelectedMunicipioId} /> |           <MunicipioSelector  | ||||||
|  |             municipios={listaMunicipios}  | ||||||
|  |             onMunicipioChange={setSelectedMunicipioId}  | ||||||
|  |           /> | ||||||
|           {selectedMunicipioId && ( |           {selectedMunicipioId && ( | ||||||
|             <div style={{ marginTop: '20px' }}> |             <div style={{ marginTop: '20px' }}> | ||||||
|               <MunicipioWidget municipioId={selectedMunicipioId} /> |               <MunicipioWidget municipioId={selectedMunicipioId} /> | ||||||
|             </div> |             </div> | ||||||
|           )} |           )} | ||||||
|  |         </div> | ||||||
|  |       </section> | ||||||
|  |        | ||||||
|  |       <section> | ||||||
|  |         {/* Usamos el ID del distrito de Bs As ("02") */} | ||||||
|  |         <ResumenProvincialWidget distritoId="02" /> | ||||||
|  |       </section> | ||||||
|  |  | ||||||
|  |       <hr /> | ||||||
|  |        | ||||||
|  |       <section> | ||||||
|  |         <h2>Consulta por Municipio</h2> | ||||||
|  |         <MunicipioSelector onMunicipioChange={setSelectedMunicipioId} municipios={[]} /> | ||||||
|  |         {selectedMunicipioId && ( | ||||||
|  |           <div style={{ marginTop: '20px' }}> | ||||||
|  |             <MunicipioWidget municipioId={selectedMunicipioId} /> | ||||||
|  |           </div> | ||||||
|  |         )} | ||||||
|  |       </section> | ||||||
|  |        | ||||||
|  |       <section> | ||||||
|  |         <h2>Proyección de Bancas</h2> | ||||||
|  |         {/* Usamos el ID de la sección de La Plata ("0001") como ejemplo */} | ||||||
|  |         <BancasWidget seccionId="0001" />  | ||||||
|  |       </section> | ||||||
|  |  | ||||||
|  |       <hr /> | ||||||
|  |        | ||||||
|  |       <section> | ||||||
|  |         <h2>Consulta de Resultados por Municipio</h2> | ||||||
|  |         <MunicipioSelector onMunicipioChange={setSelectedMunicipioId} municipios={[]} /> | ||||||
|  |         {selectedMunicipioId && ( | ||||||
|  |           <div style={{ marginTop: '20px' }}> | ||||||
|  |             <MunicipioWidget municipioId={selectedMunicipioId} /> | ||||||
|  |           </div> | ||||||
|  |         )} | ||||||
|  |       </section> | ||||||
|  |  | ||||||
|  |       <hr /> | ||||||
|  |  | ||||||
|  |       <section> | ||||||
|  |         <h2>Explorador de Telegramas</h2> | ||||||
|  |         <TelegramasView /> | ||||||
|  |       </section> | ||||||
|     </> |     </> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								Elecciones-Web/frontend/src/components/BancasWidget.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Elecciones-Web/frontend/src/components/BancasWidget.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | // src/components/BancasWidget.tsx | ||||||
|  | import { useState, useEffect } from 'react'; | ||||||
|  | import { getBancasPorSeccion, type ProyeccionBancas } from '../services/api'; | ||||||
|  |  | ||||||
|  | interface Props { | ||||||
|  |   seccionId: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const BancasWidget = ({ seccionId }: Props) => { | ||||||
|  |   const [data, setData] = useState<ProyeccionBancas | null>(null); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       try { | ||||||
|  |         setLoading(true); | ||||||
|  |         const proyeccion = await getBancasPorSeccion(seccionId); | ||||||
|  |         setData(proyeccion); | ||||||
|  |       } catch (err) { | ||||||
|  |         console.error("Error cargando bancas", err); | ||||||
|  |       } finally { | ||||||
|  |         setLoading(false); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     fetchData(); | ||||||
|  |   }, [seccionId]); | ||||||
|  |  | ||||||
|  |   if (loading) return <div>Cargando proyección de bancas...</div>; | ||||||
|  |   if (!data) return <div>No hay datos de bancas disponibles.</div>; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div style={{ fontFamily: 'sans-serif', border: '1px solid #ccc', padding: '16px', borderRadius: '8px' }}> | ||||||
|  |       <h3>Proyección de Bancas - {data.seccionNombre}</h3> | ||||||
|  |       <table style={{ width: '100%', borderCollapse: 'collapse' }}> | ||||||
|  |         <thead> | ||||||
|  |           <tr> | ||||||
|  |             <th style={{ textAlign: 'left' }}>Agrupación</th> | ||||||
|  |             <th style={{ textAlign: 'right' }}>Bancas Obtenidas</th> | ||||||
|  |           </tr> | ||||||
|  |         </thead> | ||||||
|  |         <tbody> | ||||||
|  |           {data.proyeccion.map((partido) => ( | ||||||
|  |             <tr key={partido.agrupacionNombre}> | ||||||
|  |               <td>{partido.agrupacionNombre}</td> | ||||||
|  |               <td style={{ textAlign: 'right' }}>{partido.bancas}</td> | ||||||
|  |             </tr> | ||||||
|  |           ))} | ||||||
|  |         </tbody> | ||||||
|  |       </table> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
							
								
								
									
										112
									
								
								Elecciones-Web/frontend/src/components/MapaD3Widget.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								Elecciones-Web/frontend/src/components/MapaD3Widget.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | import { useEffect, useRef, useState } from 'react'; | ||||||
|  | import * as d3 from 'd3'; | ||||||
|  | // FIX: Usamos 'import type' para los tipos y quitamos la importación de 'MunicipioSimple' | ||||||
|  | import type { FeatureCollection } from 'geojson'; | ||||||
|  |  | ||||||
|  | // --- Interfaces y Constantes --- | ||||||
|  | interface MapaResultado { | ||||||
|  |   municipioId: string; | ||||||
|  |   agrupacionGanadoraId: string; | ||||||
|  | } | ||||||
|  | const COLOR_MAP: { [key: string]: string } = { "018": "#FFC107", "025": "#03A9F4", "031": "#4CAF50", "045": "#9C27B0", "default": "#E0E0E0" }; | ||||||
|  |  | ||||||
|  | interface Props { | ||||||
|  |   onMunicipioClick: (municipioId: string) => void; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const MapaD3Widget = ({ onMunicipioClick }: Props) => { | ||||||
|  |   const svgRef = useRef<SVGSVGElement | null>(null); | ||||||
|  |   const containerRef = useRef<HTMLDivElement | null>(null); | ||||||
|  |   const [tooltip, setTooltip] = useState<{ x: number; y: number; content: string } | null>(null); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const svgElement = svgRef.current; | ||||||
|  |     const containerElement = containerRef.current; | ||||||
|  |     if (!svgElement || !containerElement) return; | ||||||
|  |  | ||||||
|  |     const drawMap = ( | ||||||
|  |       geoData: FeatureCollection, // Usamos el tipo correcto | ||||||
|  |       resultsMap: Map<string, MapaResultado>, | ||||||
|  |       idMap: Record<string, string> | ||||||
|  |     ) => { | ||||||
|  |       const { width, height } = containerElement.getBoundingClientRect(); | ||||||
|  |       if (width === 0 || height === 0) return; | ||||||
|  |  | ||||||
|  |       const svg = d3.select(svgElement); | ||||||
|  |       svg.selectAll('*').remove(); | ||||||
|  |       svg.attr('width', width).attr('height', height).attr('viewBox', `0 0 ${width} ${height}`); | ||||||
|  |  | ||||||
|  |       const projection = d3.geoMercator().fitSize([width, height], geoData); | ||||||
|  |       const pathGenerator = d3.geoPath().projection(projection); | ||||||
|  |  | ||||||
|  |       const features = geoData.features; | ||||||
|  |  | ||||||
|  |       svg.append('g') | ||||||
|  |         .selectAll('path') | ||||||
|  |         .data(features) | ||||||
|  |         .join('path') | ||||||
|  |           .attr('d', pathGenerator as any) | ||||||
|  |           .attr('stroke', '#FFFFFF') | ||||||
|  |           .attr('stroke-width', 0.5) | ||||||
|  |           .attr('fill', (d: any) => { | ||||||
|  |             const geoJsonId = d.properties.cca; | ||||||
|  |             const apiId = idMap[geoJsonId]; | ||||||
|  |             const resultado = resultsMap.get(apiId); | ||||||
|  |             return resultado ? COLOR_MAP[resultado.agrupacionGanadoraId] || COLOR_MAP.default : COLOR_MAP.default; | ||||||
|  |           }) | ||||||
|  |           .style('cursor', 'pointer') | ||||||
|  |           .on('click', (_, d: any) => { | ||||||
|  |             const apiId = idMap[d.properties.cca]; | ||||||
|  |             if (apiId) onMunicipioClick(apiId); | ||||||
|  |           }) | ||||||
|  |           .on('mouseover', (event, d: any) => { | ||||||
|  |             d3.select(event.currentTarget).attr('stroke', 'black').attr('stroke-width', 2); | ||||||
|  |             setTooltip({ x: event.pageX, y: event.pageY, content: d.properties.nam }); | ||||||
|  |           }) | ||||||
|  |           .on('mouseout', (event) => { | ||||||
|  |             d3.select(event.currentTarget).attr('stroke', '#FFFFFF').attr('stroke-width', 0.5); | ||||||
|  |             setTooltip(null); | ||||||
|  |           }); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     (async () => { | ||||||
|  |       try { | ||||||
|  |         const [geoData, resultsData, idMap] = await Promise.all([ | ||||||
|  |           d3.json<FeatureCollection>('/buenos-aires-municipios.geojson'), | ||||||
|  |           d3.json<MapaResultado[]>('http://localhost:5217/api/resultados/mapa'), | ||||||
|  |           d3.json<Record<string, string>>('/municipioIdMap.json') | ||||||
|  |         ]); | ||||||
|  |         if (geoData && resultsData && idMap) { | ||||||
|  |           const resultsMap = new Map(resultsData.map(item => [item.municipioId, item])); | ||||||
|  |           drawMap(geoData, resultsMap, idMap); | ||||||
|  |         } else { | ||||||
|  |           throw new Error("Faltan datos para renderizar el mapa."); | ||||||
|  |         } | ||||||
|  |       } catch (err) { | ||||||
|  |         console.error("Error cargando datos para el mapa:", err); | ||||||
|  |       } finally { | ||||||
|  |         setLoading(false); | ||||||
|  |       } | ||||||
|  |     })(); | ||||||
|  |   }, [onMunicipioClick]); | ||||||
|  |  | ||||||
|  |   if (loading) { | ||||||
|  |     return <div ref={containerRef} style={{ width: '100%', height: '600px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Cargando datos del mapa...</div>; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div ref={containerRef} style={{ width: '100%', height: '600px', border: '1px solid #eee' }}> | ||||||
|  |       <svg ref={svgRef}></svg> | ||||||
|  |       {tooltip && ( | ||||||
|  |           <div style={{ | ||||||
|  |               position: 'fixed', top: tooltip.y + 10, left: tooltip.x + 10, | ||||||
|  |               backgroundColor: 'rgba(0, 0, 0, 0.75)', color: 'white', padding: '8px', | ||||||
|  |               borderRadius: '4px', pointerEvents: 'none', fontSize: '14px', zIndex: 1000, | ||||||
|  |           }}> | ||||||
|  |               {tooltip.content} | ||||||
|  |           </div> | ||||||
|  |       )} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @@ -1,31 +1,11 @@ | |||||||
| // src/components/MunicipioSelector.tsx | import { type MunicipioSimple } from '../services/api'; | ||||||
| import { useState, useEffect } from 'react'; |  | ||||||
| import { getMunicipios, type MunicipioSimple } from '../services/api'; |  | ||||||
|  |  | ||||||
| interface Props { | interface Props { | ||||||
|  |   municipios: MunicipioSimple[]; | ||||||
|   onMunicipioChange: (municipioId: string) => void; |   onMunicipioChange: (municipioId: string) => void; | ||||||
| } | } | ||||||
|  |  | ||||||
| export const MunicipioSelector = ({ onMunicipioChange }: Props) => { | export const MunicipioSelector = ({ municipios, onMunicipioChange }: Props) => { | ||||||
|   const [municipios, setMunicipios] = useState<MunicipioSimple[]>([]); |  | ||||||
|   const [loading, setLoading] = useState(true); |  | ||||||
|  |  | ||||||
|   useEffect(() => { |  | ||||||
|     const loadMunicipios = async () => { |  | ||||||
|       try { |  | ||||||
|         const data = await getMunicipios(); |  | ||||||
|         setMunicipios(data); |  | ||||||
|       } catch (error) { |  | ||||||
|         console.error("Error al cargar municipios", error); |  | ||||||
|       } finally { |  | ||||||
|         setLoading(false); |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|     loadMunicipios(); |  | ||||||
|   }, []); |  | ||||||
|  |  | ||||||
|   if (loading) return <p>Cargando municipios...</p>; |  | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <select onChange={(e) => onMunicipioChange(e.target.value)} defaultValue=""> |     <select onChange={(e) => onMunicipioChange(e.target.value)} defaultValue=""> | ||||||
|       <option value="" disabled>Seleccione un municipio</option> |       <option value="" disabled>Seleccione un municipio</option> | ||||||
|   | |||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | import { useState, useEffect } from 'react'; | ||||||
|  | import { getResumenProvincial, type ResumenProvincial } from '../services/api'; | ||||||
|  |  | ||||||
|  | interface Props { | ||||||
|  |   distritoId: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const ResumenProvincialWidget = ({ distritoId }: Props) => { | ||||||
|  |   const [data, setData] = useState<ResumenProvincial | null>(null); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       try { | ||||||
|  |         const resumen = await getResumenProvincial(distritoId); | ||||||
|  |         setData(resumen); | ||||||
|  |       } catch (err) { | ||||||
|  |         console.error("Error cargando resumen provincial", err); | ||||||
|  |       } finally { | ||||||
|  |         setLoading(false); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     fetchData(); | ||||||
|  |     const intervalId = setInterval(fetchData, 15000); // Actualizamos cada 15s | ||||||
|  |     return () => clearInterval(intervalId); | ||||||
|  |   }, [distritoId]); | ||||||
|  |  | ||||||
|  |   if (loading) return <div>Cargando resumen provincial...</div>; | ||||||
|  |   if (!data) return <div>No hay datos provinciales disponibles.</div>; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div style={{ fontFamily: 'sans-serif', border: '1px solid #ccc', padding: '16px', borderRadius: '8px', backgroundColor: '#f9f9f9' }}> | ||||||
|  |       <h2>Resumen Provincial - {data.provinciaNombre}</h2> | ||||||
|  |       <p><strong>Mesas Escrutadas:</strong> {data.porcentajeEscrutado.toFixed(2)}% | <strong>Participación:</strong> {data.porcentajeParticipacion.toFixed(2)}%</p> | ||||||
|  |        | ||||||
|  |       {data.resultados.map((partido) => ( | ||||||
|  |         <div key={partido.nombre} style={{ margin: '10px 0' }}> | ||||||
|  |           <span>{partido.nombre}</span> | ||||||
|  |           <div style={{ display: 'flex', alignItems: 'center' }}> | ||||||
|  |             <div style={{ backgroundColor: '#ddd', width: '100%', borderRadius: '4px', marginRight: '10px' }}> | ||||||
|  |               <div style={{ width: `${partido.porcentaje}%`, backgroundColor: 'royalblue', color: 'white', padding: '4px', borderRadius: '4px', textAlign: 'right' }}> | ||||||
|  |                 <strong>{partido.porcentaje.toFixed(2)}%</strong> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <span>{partido.votos.toLocaleString('es-AR')}</span> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       ))} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
							
								
								
									
										65
									
								
								Elecciones-Web/frontend/src/components/TelegramasView.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								Elecciones-Web/frontend/src/components/TelegramasView.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | // src/components/TelegramasView.tsx | ||||||
|  | import { useState, useEffect } from 'react'; | ||||||
|  | import { getListaTelegramas, getTelegramaPorId, type TelegramaDetalle } from '../services/api'; | ||||||
|  |  | ||||||
|  | export const TelegramasView = () => { | ||||||
|  |   const [listaIds, setListaIds] = useState<string[]>([]); | ||||||
|  |   const [selectedTelegrama, setSelectedTelegrama] = useState<TelegramaDetalle | null>(null); | ||||||
|  |   const [loadingList, setLoadingList] = useState(true); | ||||||
|  |   const [loadingDetail, setLoadingDetail] = useState(false); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const loadList = async () => { | ||||||
|  |       try { | ||||||
|  |         const ids = await getListaTelegramas(); | ||||||
|  |         setListaIds(ids); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error al cargar lista de telegramas", error); | ||||||
|  |       } finally { | ||||||
|  |         setLoadingList(false); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     loadList(); | ||||||
|  |   }, []); | ||||||
|  |  | ||||||
|  |   const handleSelectTelegrama = async (mesaId: string) => { | ||||||
|  |     try { | ||||||
|  |         setLoadingDetail(true); | ||||||
|  |         const detalle = await getTelegramaPorId(mesaId); | ||||||
|  |         setSelectedTelegrama(detalle); | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error(`Error al cargar telegrama ${mesaId}`, error); | ||||||
|  |     } finally { | ||||||
|  |         setLoadingDetail(false); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div style={{ display: 'flex', gap: '20px', height: '500px' }}> | ||||||
|  |       <div style={{ flex: 1, border: '1px solid #ccc', overflowY: 'auto' }}> | ||||||
|  |         <h4>Telegramas Disponibles</h4> | ||||||
|  |         {loadingList ? <p>Cargando...</p> : ( | ||||||
|  |             <ul style={{ listStyle: 'none', padding: '10px' }}> | ||||||
|  |                 {listaIds.map(id => ( | ||||||
|  |                     <li key={id} onClick={() => handleSelectTelegrama(id)} style={{ cursor: 'pointer', padding: '5px', borderBottom: '1px solid #eee' }}> | ||||||
|  |                         Mesa: {id} | ||||||
|  |                     </li> | ||||||
|  |                 ))} | ||||||
|  |             </ul> | ||||||
|  |         )} | ||||||
|  |       </div> | ||||||
|  |       <div style={{ flex: 3, border: '1px solid #ccc', display: 'flex', justifyContent: 'center', alignItems: 'center' }}> | ||||||
|  |         {loadingDetail ? <p>Cargando telegrama...</p> :  | ||||||
|  |          selectedTelegrama ? ( | ||||||
|  |             <iframe  | ||||||
|  |                 src={`data:application/pdf;base64,${selectedTelegrama.contenidoBase64}`}  | ||||||
|  |                 width="100%"  | ||||||
|  |                 height="100%"  | ||||||
|  |                 title={selectedTelegrama.id} | ||||||
|  |             /> | ||||||
|  |          ) : <p>Seleccione un telegrama de la lista para visualizarlo.</p> | ||||||
|  |         } | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @@ -39,6 +39,39 @@ export interface ResumenProvincial extends Omit<MunicipioResultados, 'municipioN | |||||||
|     provinciaNombre: string; |     provinciaNombre: string; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export interface BancaResultado { | ||||||
|  |   agrupacionNombre: string; | ||||||
|  |   bancas: number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface ProyeccionBancas { | ||||||
|  |   seccionNombre: string; | ||||||
|  |   proyeccion: BancaResultado[]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface TelegramaDetalle { | ||||||
|  |     id: string; | ||||||
|  |     ambitoGeograficoId: number; | ||||||
|  |     contenidoBase64: string; | ||||||
|  |     fechaEscaneo: string; | ||||||
|  |     fechaTotalizacion: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const getBancasPorSeccion = async (seccionId: string): Promise<ProyeccionBancas> => { | ||||||
|  |     const response = await apiClient.get<ProyeccionBancas>(`/resultados/bancas/${seccionId}`); | ||||||
|  |     return response.data; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getListaTelegramas = async (): Promise<string[]> => { | ||||||
|  |     const response = await apiClient.get<string[]>('/telegramas'); | ||||||
|  |     return response.data; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getTelegramaPorId = async (mesaId: string): Promise<TelegramaDetalle> => { | ||||||
|  |     const response = await apiClient.get<TelegramaDetalle>(`/telegramas/${mesaId}`); | ||||||
|  |     return response.data; | ||||||
|  | }; | ||||||
|  |  | ||||||
| export const getMunicipios = async (): Promise<MunicipioSimple[]> => { | export const getMunicipios = async (): Promise<MunicipioSimple[]> => { | ||||||
|   const response = await apiClient.get<MunicipioSimple[]>('/catalogos/municipios'); |   const response = await apiClient.get<MunicipioSimple[]>('/catalogos/municipios'); | ||||||
|   return response.data; |   return response.data; | ||||||
|   | |||||||
| @@ -113,4 +113,78 @@ public class ResultadosController : ControllerBase | |||||||
|  |  | ||||||
|         return Ok(await Task.FromResult(respuestaSimulada)); |         return Ok(await Task.FromResult(respuestaSimulada)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [HttpGet("bancas/{seccionId}")] | ||||||
|  |     public async Task<IActionResult> GetBancasPorSeccion(string seccionId) | ||||||
|  |     { | ||||||
|  |         // 1. Buscamos el ámbito de la sección electoral | ||||||
|  |         var seccion = await _dbContext.AmbitosGeograficos | ||||||
|  |             .AsNoTracking() | ||||||
|  |             .FirstOrDefaultAsync(a => a.SeccionId == seccionId && a.NivelId == 4); // Nivel 4 = Sección Electoral | ||||||
|  |  | ||||||
|  |         if (seccion == null) | ||||||
|  |         { | ||||||
|  |             return NotFound(new { message = $"No se encontró la sección electoral con ID {seccionId}" }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 2. Buscamos todas las proyecciones para ese ámbito, incluyendo el nombre de la agrupación | ||||||
|  |         var proyecciones = await _dbContext.ProyeccionesBancas | ||||||
|  |             .AsNoTracking() | ||||||
|  |             .Include(p => p.AgrupacionPolitica) // Incluimos el nombre del partido | ||||||
|  |             .Where(p => p.AmbitoGeograficoId == seccion.Id) | ||||||
|  |             .Select(p => new | ||||||
|  |             { | ||||||
|  |                 // Creamos un objeto anónimo para la respuesta, más limpio que un DTO para este caso simple | ||||||
|  |                 AgrupacionNombre = p.AgrupacionPolitica.Nombre, | ||||||
|  |                 Bancas = p.NroBancas | ||||||
|  |             }) | ||||||
|  |             .OrderByDescending(p => p.Bancas) | ||||||
|  |             .ToListAsync(); | ||||||
|  |  | ||||||
|  |         if (!proyecciones.Any()) | ||||||
|  |         { | ||||||
|  |             return NotFound(new { message = $"No se han encontrado proyecciones de bancas para la sección {seccion.Nombre}" }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 3. Devolvemos un objeto que contiene el nombre de la sección y la lista de resultados | ||||||
|  |         return Ok(new | ||||||
|  |         { | ||||||
|  |             SeccionNombre = seccion.Nombre, | ||||||
|  |             Proyeccion = proyecciones | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpGet("mapa")] | ||||||
|  |     public async Task<IActionResult> GetResultadosParaMapa() | ||||||
|  |     { | ||||||
|  |         // Esta consulta es mucho más eficiente y se traduce bien a SQL. | ||||||
|  |         // Paso 1: Para cada ámbito, encontrar la cantidad máxima de votos. | ||||||
|  |         var maxVotosPorAmbito = _dbContext.ResultadosVotos | ||||||
|  |             .GroupBy(rv => rv.AmbitoGeograficoId) | ||||||
|  |             .Select(g => new | ||||||
|  |             { | ||||||
|  |                 AmbitoId = g.Key, | ||||||
|  |                 MaxVotos = g.Max(v => v.CantidadVotos) | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |         // Paso 2: Unir los resultados originales con los máximos para encontrar el registro ganador. | ||||||
|  |         // Esto nos da, para cada ámbito, el registro completo del partido que tuvo más votos. | ||||||
|  |         var resultadosGanadores = await _dbContext.ResultadosVotos | ||||||
|  |             .Join( | ||||||
|  |                 maxVotosPorAmbito, | ||||||
|  |                 voto => new { AmbitoId = voto.AmbitoGeograficoId, Votos = voto.CantidadVotos }, | ||||||
|  |                 max => new { AmbitoId = max.AmbitoId, Votos = max.MaxVotos }, | ||||||
|  |                 (voto, max) => voto // Nos quedamos con el objeto 'ResultadoVoto' completo | ||||||
|  |             ) | ||||||
|  |             .Include(rv => rv.AmbitoGeografico) // Incluimos el ámbito para obtener el MunicipioId | ||||||
|  |             .Where(rv => rv.AmbitoGeografico.MunicipioId != null) | ||||||
|  |             .Select(rv => new | ||||||
|  |             { | ||||||
|  |                 MunicipioId = rv.AmbitoGeografico.MunicipioId, | ||||||
|  |                 AgrupacionGanadoraId = rv.AgrupacionPoliticaId | ||||||
|  |             }) | ||||||
|  |             .ToListAsync(); | ||||||
|  |  | ||||||
|  |         return Ok(resultadosGanadores); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -0,0 +1,62 @@ | |||||||
|  | using Elecciones.Core.DTOs.ApiResponses; | ||||||
|  | using Elecciones.Database; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Api.Controllers; | ||||||
|  |  | ||||||
|  | [ApiController] | ||||||
|  | [Route("api/[controller]")] | ||||||
|  | public class TelegramasController : ControllerBase | ||||||
|  | { | ||||||
|  |   private readonly EleccionesDbContext _dbContext; | ||||||
|  |  | ||||||
|  |   public TelegramasController(EleccionesDbContext dbContext) | ||||||
|  |   { | ||||||
|  |     _dbContext = dbContext; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /// <summary> | ||||||
|  |   /// Obtiene la lista de IDs de todos los telegramas que han sido totalizados y descargados. | ||||||
|  |   /// </summary> | ||||||
|  |   [HttpGet] | ||||||
|  |   public async Task<IActionResult> GetListaTelegramas() | ||||||
|  |   { | ||||||
|  |     var ids = await _dbContext.Telegramas | ||||||
|  |         .AsNoTracking() | ||||||
|  |         .OrderBy(t => t.Id) | ||||||
|  |         .Select(t => t.Id) | ||||||
|  |         .ToListAsync(); | ||||||
|  |  | ||||||
|  |     return Ok(ids); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /// <summary> | ||||||
|  |   /// Obtiene el contenido completo de un telegrama específico, incluyendo la imagen en Base64. | ||||||
|  |   /// </summary> | ||||||
|  |   /// <param name="mesaId">El ID único de la mesa/telegrama (ej. "0200100001M").</param> | ||||||
|  |   [HttpGet("{mesaId}")] | ||||||
|  |   public async Task<IActionResult> GetTelegramaPorId(string mesaId) | ||||||
|  |   { | ||||||
|  |     var telegrama = await _dbContext.Telegramas | ||||||
|  |         .AsNoTracking() | ||||||
|  |         .FirstOrDefaultAsync(t => t.Id == mesaId); | ||||||
|  |  | ||||||
|  |     if (telegrama == null) | ||||||
|  |     { | ||||||
|  |       return NotFound(new { message = $"No se encontró el telegrama con ID {mesaId}" }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Devolvemos todos los datos del telegrama | ||||||
|  |     return Ok(new | ||||||
|  |     { | ||||||
|  |       telegrama.Id, | ||||||
|  |       telegrama.AmbitoGeograficoId, | ||||||
|  |       telegrama.ContenidoBase64, | ||||||
|  |       telegrama.FechaEscaneo, | ||||||
|  |       telegrama.FechaTotalizacion | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -14,6 +14,8 @@ | |||||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|       <PrivateAssets>all</PrivateAssets> |       <PrivateAssets>all</PrivateAssets> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|  |     <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" /> | ||||||
|  |     <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> | ||||||
|     <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /> |     <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,30 +1,26 @@ | |||||||
| using Elecciones.Database; | using Elecciones.Database; | ||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Serilog; | ||||||
|  |  | ||||||
|  | // Esta es la estructura estándar y recomendada. | ||||||
| var builder = WebApplication.CreateBuilder(args); | var builder = WebApplication.CreateBuilder(args); | ||||||
|  |  | ||||||
| // --- 1. Configuración de Servicios --- | // 1. Configurar Serilog. Esta es la forma correcta de integrarlo. | ||||||
|  | builder.Host.UseSerilog((context, services, configuration) => configuration | ||||||
|  |     .ReadFrom.Configuration(context.Configuration) | ||||||
|  |     .ReadFrom.Services(services) | ||||||
|  |     .Enrich.FromLogContext() | ||||||
|  |     .WriteTo.Console() | ||||||
|  |     .WriteTo.File("logs/api-.log", rollingInterval: RollingInterval.Day)); | ||||||
|  |  | ||||||
| // Añade la cadena de conexión y el DbContext para Entity Framework Core. | // 2. Añadir servicios al contenedor. | ||||||
| var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); | var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); | ||||||
| builder.Services.AddDbContext<EleccionesDbContext>(options => | builder.Services.AddDbContext<EleccionesDbContext>(options => | ||||||
|     options.UseSqlServer(connectionString)); |     options.UseSqlServer(connectionString)); | ||||||
|  |  | ||||||
| // Añade los servicios para los controladores de la API. |  | ||||||
| builder.Services.AddControllers(); | builder.Services.AddControllers(); | ||||||
|  |  | ||||||
| // Configura CORS para permitir que tu frontend (y www.eldia.com) consuman la API. | var allowedOrigins = builder.Configuration["AllowedOrigins"]?.Split(',') ?? Array.Empty<string>(); | ||||||
| // builder.Services.AddCors(options => |  | ||||||
| // { |  | ||||||
| //     options.AddDefaultPolicy(policy => |  | ||||||
| //     { |  | ||||||
| //         policy.WithOrigins("http://localhost:5173", "http://localhost:8600", "http://www.eldia.com", "http://elecciones2025.eldia.com") |  | ||||||
| //               .AllowAnyHeader() |  | ||||||
| //               .AllowAnyMethod(); |  | ||||||
| //     }); |  | ||||||
| // }); |  | ||||||
|  |  | ||||||
| var allowedOrigins = builder.Configuration["AllowedOrigins"]?.Split(',') ?? []; |  | ||||||
| builder.Services.AddCors(options => | builder.Services.AddCors(options => | ||||||
| { | { | ||||||
|     options.AddDefaultPolicy(policy => |     options.AddDefaultPolicy(policy => | ||||||
| @@ -38,34 +34,28 @@ builder.Services.AddCors(options => | |||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
| // Añade la configuración de Swagger/OpenAPI para la documentación de la API. |  | ||||||
| builder.Services.AddEndpointsApiExplorer(); | builder.Services.AddEndpointsApiExplorer(); | ||||||
| builder.Services.AddSwaggerGen(); | builder.Services.AddSwaggerGen(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // 3. Construir la aplicación. | ||||||
| var app = builder.Build(); | var app = builder.Build(); | ||||||
|  |  | ||||||
| // --- 2. Configuración del Pipeline de Peticiones HTTP --- | // 4. Configurar el pipeline de peticiones HTTP. | ||||||
|  | // Añadimos el logging de peticiones de Serilog aquí. | ||||||
|  | app.UseSerilogRequestLogging(); | ||||||
|  |  | ||||||
| // Habilita la UI de Swagger en el entorno de desarrollo. |  | ||||||
| if (app.Environment.IsDevelopment()) | if (app.Environment.IsDevelopment()) | ||||||
| { | { | ||||||
|     app.UseSwagger(); |     app.UseSwagger(); | ||||||
|     app.UseSwaggerUI(); |     app.UseSwaggerUI(); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Redirige las peticiones HTTP a HTTPS. |  | ||||||
| app.UseHttpsRedirection(); | app.UseHttpsRedirection(); | ||||||
|  |  | ||||||
| // Usa la política de CORS que definimos arriba. |  | ||||||
| app.UseCors(); | app.UseCors(); | ||||||
|  |  | ||||||
| // Habilita la autorización (lo configuraremos si es necesario más adelante). |  | ||||||
| app.UseAuthorization(); | app.UseAuthorization(); | ||||||
|  |  | ||||||
| // Mapea las rutas a los controladores de la API. |  | ||||||
| app.MapControllers(); | app.MapControllers(); | ||||||
|  |  | ||||||
| // Inicia la aplicación. | // 5. Ejecutar la aplicación. | ||||||
|  | // El try/catch/finally se puede omitir; el logging de Serilog ya se encarga de los errores fatales. | ||||||
| app.Run(); | app.Run(); | ||||||
| @@ -13,6 +13,8 @@ | |||||||
|           "Microsoft.AspNetCore.OpenApi": "9.0.5", |           "Microsoft.AspNetCore.OpenApi": "9.0.5", | ||||||
|           "Microsoft.EntityFrameworkCore.SqlServer": "9.0.8", |           "Microsoft.EntityFrameworkCore.SqlServer": "9.0.8", | ||||||
|           "Microsoft.EntityFrameworkCore.Tools": "9.0.8", |           "Microsoft.EntityFrameworkCore.Tools": "9.0.8", | ||||||
|  |           "Serilog.AspNetCore": "9.0.0", | ||||||
|  |           "Serilog.Sinks.File": "7.0.0", | ||||||
|           "Swashbuckle.AspNetCore": "9.0.3" |           "Swashbuckle.AspNetCore": "9.0.3" | ||||||
|         }, |         }, | ||||||
|         "runtime": { |         "runtime": { | ||||||
| @@ -626,6 +628,20 @@ | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |       "Microsoft.Extensions.FileProviders.Abstractions/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Primitives": "9.0.8" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Hosting.Abstractions/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.FileProviders.Abstractions": "9.0.0", | ||||||
|  |           "Microsoft.Extensions.Logging.Abstractions": "9.0.8" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|       "Microsoft.Extensions.Http/9.0.8": { |       "Microsoft.Extensions.Http/9.0.8": { | ||||||
|         "dependencies": { |         "dependencies": { | ||||||
|           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
| @@ -840,6 +856,115 @@ | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |       "Serilog/4.2.0": { | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.dll": { | ||||||
|  |             "assemblyVersion": "4.2.0.0", | ||||||
|  |             "fileVersion": "4.2.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.AspNetCore/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0", | ||||||
|  |           "Serilog.Extensions.Hosting": "9.0.0", | ||||||
|  |           "Serilog.Formatting.Compact": "3.0.0", | ||||||
|  |           "Serilog.Settings.Configuration": "9.0.0", | ||||||
|  |           "Serilog.Sinks.Console": "6.0.0", | ||||||
|  |           "Serilog.Sinks.Debug": "3.0.0", | ||||||
|  |           "Serilog.Sinks.File": "7.0.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.AspNetCore.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Extensions.Hosting/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Hosting.Abstractions": "9.0.0", | ||||||
|  |           "Microsoft.Extensions.Logging.Abstractions": "9.0.8", | ||||||
|  |           "Serilog": "4.2.0", | ||||||
|  |           "Serilog.Extensions.Logging": "9.0.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Extensions.Hosting.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Extensions.Logging/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Logging": "9.0.8", | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Extensions.Logging.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Formatting.Compact/3.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net8.0/Serilog.Formatting.Compact.dll": { | ||||||
|  |             "assemblyVersion": "3.0.0.0", | ||||||
|  |             "fileVersion": "3.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Settings.Configuration/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Binder": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.DependencyModel": "9.0.8", | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Settings.Configuration.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Sinks.Console/6.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net8.0/Serilog.Sinks.Console.dll": { | ||||||
|  |             "assemblyVersion": "6.0.0.0", | ||||||
|  |             "fileVersion": "6.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Sinks.Debug/3.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net8.0/Serilog.Sinks.Debug.dll": { | ||||||
|  |             "assemblyVersion": "3.0.0.0", | ||||||
|  |             "fileVersion": "3.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Sinks.File/7.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Sinks.File.dll": { | ||||||
|  |             "assemblyVersion": "7.0.0.0", | ||||||
|  |             "fileVersion": "7.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|       "Swashbuckle.AspNetCore/9.0.3": { |       "Swashbuckle.AspNetCore/9.0.3": { | ||||||
|         "dependencies": { |         "dependencies": { | ||||||
|           "Microsoft.Extensions.ApiDescription.Server": "9.0.0", |           "Microsoft.Extensions.ApiDescription.Server": "9.0.0", | ||||||
| @@ -1426,6 +1551,20 @@ | |||||||
|       "path": "microsoft.extensions.diagnostics.abstractions/9.0.8", |       "path": "microsoft.extensions.diagnostics.abstractions/9.0.8", | ||||||
|       "hashPath": "microsoft.extensions.diagnostics.abstractions.9.0.8.nupkg.sha512" |       "hashPath": "microsoft.extensions.diagnostics.abstractions.9.0.8.nupkg.sha512" | ||||||
|     }, |     }, | ||||||
|  |     "Microsoft.Extensions.FileProviders.Abstractions/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-uK439QzYR0q2emLVtYzwyK3x+T5bTY4yWsd/k/ZUS9LR6Sflp8MIdhGXW8kQCd86dQD4tLqvcbLkku8qHY263Q==", | ||||||
|  |       "path": "microsoft.extensions.fileproviders.abstractions/9.0.0", | ||||||
|  |       "hashPath": "microsoft.extensions.fileproviders.abstractions.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Hosting.Abstractions/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-yUKJgu81ExjvqbNWqZKshBbLntZMbMVz/P7Way2SBx7bMqA08Mfdc9O7hWDKAiSp+zPUGT6LKcSCQIPeDK+CCw==", | ||||||
|  |       "path": "microsoft.extensions.hosting.abstractions/9.0.0", | ||||||
|  |       "hashPath": "microsoft.extensions.hosting.abstractions.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|     "Microsoft.Extensions.Http/9.0.8": { |     "Microsoft.Extensions.Http/9.0.8": { | ||||||
|       "type": "package", |       "type": "package", | ||||||
|       "serviceable": true, |       "serviceable": true, | ||||||
| @@ -1566,6 +1705,69 @@ | |||||||
|       "path": "mono.texttemplating/3.0.0", |       "path": "mono.texttemplating/3.0.0", | ||||||
|       "hashPath": "mono.texttemplating.3.0.0.nupkg.sha512" |       "hashPath": "mono.texttemplating.3.0.0.nupkg.sha512" | ||||||
|     }, |     }, | ||||||
|  |     "Serilog/4.2.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-gmoWVOvKgbME8TYR+gwMf7osROiWAURterc6Rt2dQyX7wtjZYpqFiA/pY6ztjGQKKV62GGCyOcmtP1UKMHgSmA==", | ||||||
|  |       "path": "serilog/4.2.0", | ||||||
|  |       "hashPath": "serilog.4.2.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.AspNetCore/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-JslDajPlBsn3Pww1554flJFTqROvK9zz9jONNQgn0D8Lx2Trw8L0A8/n6zEQK1DAZWXrJwiVLw8cnTR3YFuYsg==", | ||||||
|  |       "path": "serilog.aspnetcore/9.0.0", | ||||||
|  |       "hashPath": "serilog.aspnetcore.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Extensions.Hosting/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-u2TRxuxbjvTAldQn7uaAwePkWxTHIqlgjelekBtilAGL5sYyF3+65NWctN4UrwwGLsDC7c3Vz3HnOlu+PcoxXg==", | ||||||
|  |       "path": "serilog.extensions.hosting/9.0.0", | ||||||
|  |       "hashPath": "serilog.extensions.hosting.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Extensions.Logging/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==", | ||||||
|  |       "path": "serilog.extensions.logging/9.0.0", | ||||||
|  |       "hashPath": "serilog.extensions.logging.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Formatting.Compact/3.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-wQsv14w9cqlfB5FX2MZpNsTawckN4a8dryuNGbebB/3Nh1pXnROHZov3swtu3Nj5oNG7Ba+xdu7Et/ulAUPanQ==", | ||||||
|  |       "path": "serilog.formatting.compact/3.0.0", | ||||||
|  |       "hashPath": "serilog.formatting.compact.3.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Settings.Configuration/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-4/Et4Cqwa+F88l5SeFeNZ4c4Z6dEAIKbu3MaQb2Zz9F/g27T5a3wvfMcmCOaAiACjfUb4A6wrlTVfyYUZk3RRQ==", | ||||||
|  |       "path": "serilog.settings.configuration/9.0.0", | ||||||
|  |       "hashPath": "serilog.settings.configuration.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Sinks.Console/6.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-fQGWqVMClCP2yEyTXPIinSr5c+CBGUvBybPxjAGcf7ctDhadFhrQw03Mv8rJ07/wR5PDfFjewf2LimvXCDzpbA==", | ||||||
|  |       "path": "serilog.sinks.console/6.0.0", | ||||||
|  |       "hashPath": "serilog.sinks.console.6.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Sinks.Debug/3.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-4BzXcdrgRX7wde9PmHuYd9U6YqycCC28hhpKonK7hx0wb19eiuRj16fPcPSVp0o/Y1ipJuNLYQ00R3q2Zs8FDA==", | ||||||
|  |       "path": "serilog.sinks.debug/3.0.0", | ||||||
|  |       "hashPath": "serilog.sinks.debug.3.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Sinks.File/7.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-fKL7mXv7qaiNBUC71ssvn/dU0k9t0o45+qm2XgKAlSt19xF+ijjxyA3R6HmCgfKEKwfcfkwWjayuQtRueZFkYw==", | ||||||
|  |       "path": "serilog.sinks.file/7.0.0", | ||||||
|  |       "hashPath": "serilog.sinks.file.7.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|     "Swashbuckle.AspNetCore/9.0.3": { |     "Swashbuckle.AspNetCore/9.0.3": { | ||||||
|       "type": "package", |       "type": "package", | ||||||
|       "serviceable": true, |       "serviceable": true, | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -14,7 +14,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1d580231134cc923bf8cbc524140ceb0ae88752f")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -173,3 +173,13 @@ E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft. | |||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Diagnostics.Abstractions.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Diagnostics.Abstractions.dll | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Http.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Http.dll | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\buenos-aires-municipios.geojson | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.AspNetCore.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Extensions.Hosting.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Extensions.Logging.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Formatting.Compact.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Settings.Configuration.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Sinks.Console.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Sinks.Debug.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Api\bin\Debug\net9.0\Serilog.Sinks.File.dll | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| {"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","AE1TAk4qas82IfXTyRHo\u002BfMlnTE4e7B1AJrEn9ZhBwo=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","ywKm3DCyXg4YCbZAIx3JUlT8N4Irff3GswYUVDST\u002BjQ=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","r5wfLIFTEo2\u002Bd7Tsx44bFIb0SPNdPvg4KbBRNmbWVFA="],"CachedAssets":{},"CachedCopyCandidates":{}} | {"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","ywKm3DCyXg4YCbZAIx3JUlT8N4Irff3GswYUVDST\u002BjQ=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","/FHWuH7ftxc5u992j4YhVijd0fBiiQLWe\u002BV0ZlveX5c="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||||
| @@ -1 +1 @@ | |||||||
| {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","AE1TAk4qas82IfXTyRHo\u002BfMlnTE4e7B1AJrEn9ZhBwo=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","ywKm3DCyXg4YCbZAIx3JUlT8N4Irff3GswYUVDST\u002BjQ=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","r5wfLIFTEo2\u002Bd7Tsx44bFIb0SPNdPvg4KbBRNmbWVFA="],"CachedAssets":{},"CachedCopyCandidates":{}} | {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","ywKm3DCyXg4YCbZAIx3JUlT8N4Irff3GswYUVDST\u002BjQ=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","/FHWuH7ftxc5u992j4YhVijd0fBiiQLWe\u002BV0ZlveX5c="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||||
| @@ -1 +1 @@ | |||||||
| {"GlobalPropertiesHash":"O7YawHw32G/Fh2bs+snZgm9O7okI0WYgTQmXM931znY=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","AE1TAk4qas82IfXTyRHo\u002BfMlnTE4e7B1AJrEn9ZhBwo="],"CachedAssets":{},"CachedCopyCandidates":{}} | {"GlobalPropertiesHash":"O7YawHw32G/Fh2bs+snZgm9O7okI0WYgTQmXM931znY=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["mhE0FuBM0BOF9SNOE0rY9setCw2ye3UUh7cEPjhgDdY=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||||
| @@ -71,6 +71,14 @@ | |||||||
|               "target": "Package", |               "target": "Package", | ||||||
|               "version": "[9.0.8, )" |               "version": "[9.0.8, )" | ||||||
|             }, |             }, | ||||||
|  |             "Serilog.AspNetCore": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[9.0.0, )" | ||||||
|  |             }, | ||||||
|  |             "Serilog.Sinks.File": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[7.0.0, )" | ||||||
|  |             }, | ||||||
|             "Swashbuckle.AspNetCore": { |             "Swashbuckle.AspNetCore": { | ||||||
|               "target": "Package", |               "target": "Package", | ||||||
|               "version": "[9.0.3, )" |               "version": "[9.0.3, )" | ||||||
|   | |||||||
| @@ -3,10 +3,10 @@ | |||||||
|   <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |   <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> | ||||||
|     <Import Project="$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets')" /> |     <Import Project="$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\9.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\9.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.apidescription.server\9.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.apidescription.server\9.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)mono.texttemplating\3.0.0\buildTransitive\Mono.TextTemplating.targets" Condition="Exists('$(NuGetPackageRoot)mono.texttemplating\3.0.0\buildTransitive\Mono.TextTemplating.targets')" /> |  | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" /> |  | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" /> | ||||||
|  |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> | ||||||
|  |     <Import Project="$(NuGetPackageRoot)mono.texttemplating\3.0.0\buildTransitive\Mono.TextTemplating.targets" Condition="Exists('$(NuGetPackageRoot)mono.texttemplating\3.0.0\buildTransitive\Mono.TextTemplating.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets')" /> | ||||||
|   </ImportGroup> |   </ImportGroup> | ||||||
| </Project> | </Project> | ||||||
							
								
								
									
										20
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/BancaDto.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/BancaDto.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | // src/Elecciones.Core/DTOs/BancaDto.cs | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  | namespace Elecciones.Core.DTOs; | ||||||
|  |  | ||||||
|  | public class BancaDto | ||||||
|  | { | ||||||
|  |   [JsonPropertyName("idAgrupacion")] | ||||||
|  |   public string IdAgrupacion { get; set; } = null!; | ||||||
|  |   [JsonPropertyName("nombreAgrupacion")] | ||||||
|  |   public string NombreAgrupacion { get; set; } = null!; | ||||||
|  |  | ||||||
|  |   [JsonPropertyName("nroBancas")] | ||||||
|  |   public int NroBancas { get; set; } | ||||||
|  |  | ||||||
|  |   public class RepartoBancasDto | ||||||
|  |   { | ||||||
|  |     [JsonPropertyName("repartoBancas")] | ||||||
|  |     public List<BancaDto> RepartoBancas { get; set; } = []; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/CategoriaDto.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/CategoriaDto.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Core.DTOs; | ||||||
|  |  | ||||||
|  | public class CategoriaDto | ||||||
|  | { | ||||||
|  |     [JsonPropertyName("orden")] | ||||||
|  |     public int Orden { get; set; } | ||||||
|  |  | ||||||
|  |     [JsonPropertyName("categoriald")] | ||||||
|  |     public int CategoriaId { get; set; } | ||||||
|  |  | ||||||
|  |     [JsonPropertyName("nombre")] | ||||||
|  |     public string Nombre { get; set; } = null!; | ||||||
|  | } | ||||||
| @@ -1,4 +1,3 @@ | |||||||
| // src/Elecciones.Core/DTOs/EstadoRecuentoDto.cs |  | ||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| namespace Elecciones.Core.DTOs; | namespace Elecciones.Core.DTOs; | ||||||
| @@ -11,9 +10,15 @@ public class EstadoRecuentoDto | |||||||
|     [JsonPropertyName("mesasTotalizadas")] |     [JsonPropertyName("mesasTotalizadas")] | ||||||
|     public int MesasTotalizadas { get; set; } |     public int MesasTotalizadas { get; set; } | ||||||
|      |      | ||||||
|  |     [JsonPropertyName("mesasTotalizadasPorcentaje")] | ||||||
|  |     public decimal MesasTotalizadasPorcentaje { get; set; } | ||||||
|  |  | ||||||
|     [JsonPropertyName("cantidadElectores")] |     [JsonPropertyName("cantidadElectores")] | ||||||
|     public int CantidadElectores { get; set; } |     public int CantidadElectores { get; set; } | ||||||
|      |      | ||||||
|  |     [JsonPropertyName("cantidadVotantes")] | ||||||
|  |     public int CantidadVotantes { get; set; } | ||||||
|  |  | ||||||
|     [JsonPropertyName("participacionPorcentaje")] |     [JsonPropertyName("participacionPorcentaje")] | ||||||
|     public decimal ParticipacionPorcentaje { get; set; } |     public decimal ParticipacionPorcentaje { get; set; } | ||||||
| } | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Core.DTOs; | ||||||
|  |  | ||||||
|  | // Reutilizamos el DTO de estado de recuento que ya teníamos, | ||||||
|  | // pero le damos un alias para claridad si es necesario. | ||||||
|  | // A nivel de estructura son idénticos. | ||||||
|  | public class EstadoRecuentoGeneralDto : EstadoRecuentoDto { } | ||||||
							
								
								
									
										22
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/ResumenDto.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/ResumenDto.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | using System.Text.Json.Serialization; | ||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Core.DTOs; | ||||||
|  |  | ||||||
|  | public class ResumenDto | ||||||
|  | { | ||||||
|  |     [JsonPropertyName("valoresTotalizadosPositivos")] | ||||||
|  |     public List<ResumenPositivoDto> ValoresTotalizadosPositivos { get; set; } = []; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class ResumenPositivoDto | ||||||
|  | { | ||||||
|  |     [JsonPropertyName("idAgrupacion")] | ||||||
|  |     public string IdAgrupacion { get; set; } = null!; | ||||||
|  |      | ||||||
|  |     [JsonPropertyName("votos")] | ||||||
|  |     public long Votos { get; set; } | ||||||
|  |  | ||||||
|  |     [JsonPropertyName("votosPorcentaje")] | ||||||
|  |     public decimal VotosPorcentaje { get; set; } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/TelegramaFileDto.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Elecciones-Web/src/Elecciones.Core/DTOs/TelegramaFileDto.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | // src/Elecciones.Core/DTOs/TelegramaFileDto.cs | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Core.DTOs; | ||||||
|  |  | ||||||
|  | public class TelegramaFileDto | ||||||
|  | { | ||||||
|  |     [JsonPropertyName("nombreArchivo")] | ||||||
|  |     public string NombreArchivo { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [JsonPropertyName("imagen")] | ||||||
|  |     public string Imagen { get; set; } = null!; | ||||||
|  |      | ||||||
|  |     [JsonPropertyName("fechaEscaneo")] | ||||||
|  |     public string FechaEscaneo { get; set; } = null!; | ||||||
|  |      | ||||||
|  |     [JsonPropertyName("fechaTotalizacion")] | ||||||
|  |     public string FechaTotalizacion { get; set; } = null!; | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | { | ||||||
|  |   "runtimeTarget": { | ||||||
|  |     "name": ".NETCoreApp,Version=v9.0", | ||||||
|  |     "signature": "" | ||||||
|  |   }, | ||||||
|  |   "compilationOptions": {}, | ||||||
|  |   "targets": { | ||||||
|  |     ".NETCoreApp,Version=v9.0": { | ||||||
|  |       "Elecciones.Core/1.0.0": { | ||||||
|  |         "runtime": { | ||||||
|  |           "Elecciones.Core.dll": {} | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "libraries": { | ||||||
|  |     "Elecciones.Core/1.0.0": { | ||||||
|  |       "type": "project", | ||||||
|  |       "serviceable": false, | ||||||
|  |       "sha512": "" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b90baadeedb870b5b1c9eeeb7022a0d211b61bec")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | // <autogenerated /> | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // <auto-generated> | ||||||
|  | //     This code was generated by a tool. | ||||||
|  | // | ||||||
|  | //     Changes to this file may cause incorrect behavior and will be lost if | ||||||
|  | //     the code is regenerated. | ||||||
|  | // </auto-generated> | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | ||||||
|  | [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] | ||||||
|  | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
|  | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
|  | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | ||||||
|  | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | ||||||
|  | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|  |  | ||||||
|  | // Generado por la clase WriteCodeFragment de MSBuild. | ||||||
|  |  | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | is_global = true | ||||||
|  | build_property.TargetFramework = net9.0 | ||||||
|  | build_property.TargetPlatformMinVersion =  | ||||||
|  | build_property.UsingMicrosoftNETSdkWeb =  | ||||||
|  | build_property.ProjectTypeGuids =  | ||||||
|  | build_property.InvariantGlobalization =  | ||||||
|  | build_property.PlatformNeutralAssembly =  | ||||||
|  | build_property.EnforceExtendedAnalyzerRules =  | ||||||
|  | build_property._SupportedPlatformList = Linux,macOS,Windows | ||||||
|  | build_property.RootNamespace = Elecciones.Core | ||||||
|  | build_property.ProjectDir = E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\ | ||||||
|  | build_property.EnableComHosting =  | ||||||
|  | build_property.EnableGeneratedComInterfaceComImportInterop =  | ||||||
|  | build_property.EffectiveAnalysisLevelStyle = 9.0 | ||||||
|  | build_property.EnableCodeStyleSeverity =  | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | // <auto-generated/> | ||||||
|  | global using global::System; | ||||||
|  | global using global::System.Collections.Generic; | ||||||
|  | global using global::System.IO; | ||||||
|  | global using global::System.Linq; | ||||||
|  | global using global::System.Net.Http; | ||||||
|  | global using global::System.Threading; | ||||||
|  | global using global::System.Threading.Tasks; | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\bin\Release\net9.0\Elecciones.Core.deps.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\bin\Release\net9.0\Elecciones.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\bin\Release\net9.0\Elecciones.Core.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.GeneratedMSBuildEditorConfig.editorconfig | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.AssemblyInfoInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.AssemblyInfo.cs | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.csproj.CoreCompileInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\refint\Elecciones.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\Elecciones.Core.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Core\obj\Release\net9.0\ref\Elecciones.Core.dll | ||||||
| @@ -10,7 +10,11 @@ public class EleccionesDbContext(DbContextOptions<EleccionesDbContext> options) | |||||||
|     public DbSet<AmbitoGeografico> AmbitosGeograficos { get; set; } |     public DbSet<AmbitoGeografico> AmbitosGeograficos { get; set; } | ||||||
|     public DbSet<ResultadoVoto> ResultadosVotos { get; set; } |     public DbSet<ResultadoVoto> ResultadosVotos { get; set; } | ||||||
|     public DbSet<EstadoRecuento> EstadosRecuentos { get; set; } |     public DbSet<EstadoRecuento> EstadosRecuentos { get; set; } | ||||||
|     // Podríamos añadir más tablas como CategoriaElectoral o ProyeccionBanca aquí |     public DbSet<ProyeccionBanca> ProyeccionesBancas { get; set; } | ||||||
|  |     public DbSet<Telegrama> Telegramas { get; set; } | ||||||
|  |     public DbSet<ResumenVoto> ResumenesVotos { get; set; } | ||||||
|  |     public DbSet<EstadoRecuentoGeneral> EstadosRecuentosGenerales { get; set; } | ||||||
|  |     public DbSet<CategoriaElectoral> CategoriasElectorales { get; set; } | ||||||
|  |  | ||||||
|     protected override void OnModelCreating(ModelBuilder modelBuilder) |     protected override void OnModelCreating(ModelBuilder modelBuilder) | ||||||
|     { |     { | ||||||
| @@ -27,5 +31,13 @@ public class EleccionesDbContext(DbContextOptions<EleccionesDbContext> options) | |||||||
|             entity.Property(e => e.MesasTotalizadasPorcentaje).HasPrecision(5, 2); |             entity.Property(e => e.MesasTotalizadasPorcentaje).HasPrecision(5, 2); | ||||||
|             entity.Property(e => e.ParticipacionPorcentaje).HasPrecision(5, 2); |             entity.Property(e => e.ParticipacionPorcentaje).HasPrecision(5, 2); | ||||||
|         }); |         }); | ||||||
|  |         modelBuilder.Entity<ResumenVoto>() | ||||||
|  |         .Property(e => e.VotosPorcentaje).HasPrecision(5, 2); | ||||||
|  |  | ||||||
|  |         modelBuilder.Entity<EstadoRecuentoGeneral>(entity => | ||||||
|  |         { | ||||||
|  |             entity.Property(e => e.MesasTotalizadasPorcentaje).HasPrecision(5, 2); | ||||||
|  |             entity.Property(e => e.ParticipacionPorcentaje).HasPrecision(5, 2); | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Entities; | ||||||
|  |  | ||||||
|  | public class CategoriaElectoral | ||||||
|  | { | ||||||
|  |     [Key] | ||||||
|  |     [DatabaseGenerated(DatabaseGeneratedOption.None)] // La API nos da el ID, no la BD. | ||||||
|  |     public int Id { get; set; } // Corresponde a 'categoriald' | ||||||
|  |  | ||||||
|  |     [Required] | ||||||
|  |     public string Nombre { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     public int Orden { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Entities; | ||||||
|  |  | ||||||
|  | public class EstadoRecuentoGeneral | ||||||
|  | { | ||||||
|  |     [Key] | ||||||
|  |     [DatabaseGenerated(DatabaseGeneratedOption.None)] // Le dice a EF que no genere este valor. | ||||||
|  |     public int AmbitoGeograficoId { get; set; } | ||||||
|  |  | ||||||
|  |     public int MesasEsperadas { get; set; } | ||||||
|  |     public int MesasTotalizadas { get; set; } | ||||||
|  |     public decimal MesasTotalizadasPorcentaje { get; set; } | ||||||
|  |     public int CantidadElectores { get; set; } | ||||||
|  |     public int CantidadVotantes { get; set; } | ||||||
|  |     public decimal ParticipacionPorcentaje { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | // src/Elecciones.Database/Entities/ProyeccionBanca.cs | ||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Entities; | ||||||
|  |  | ||||||
|  | public class ProyeccionBanca | ||||||
|  | { | ||||||
|  |     [Key] | ||||||
|  |     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||||||
|  |     public int Id { get; set; } | ||||||
|  |  | ||||||
|  |     // El ámbito donde se proyecta (ej. Sección Electoral) | ||||||
|  |     public int AmbitoGeograficoId { get; set; } | ||||||
|  |     [ForeignKey("AmbitoGeograficoId")] | ||||||
|  |     public AmbitoGeografico AmbitoGeografico { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     // La agrupación que obtiene la banca | ||||||
|  |     public string AgrupacionPoliticaId { get; set; } = null!; | ||||||
|  |     [ForeignKey("AgrupacionPoliticaId")] | ||||||
|  |     public AgrupacionPolitica AgrupacionPolitica { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     // Cantidad de bancas obtenidas | ||||||
|  |     public int NroBancas { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Entities; | ||||||
|  |  | ||||||
|  | public class ResumenVoto | ||||||
|  | { | ||||||
|  |     [Key] | ||||||
|  |     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||||||
|  |     public int Id { get; set; } | ||||||
|  |  | ||||||
|  |     // El ámbito donde se resume (siempre provincial en este caso) | ||||||
|  |     public int AmbitoGeograficoId { get; set; } | ||||||
|  |  | ||||||
|  |     public string AgrupacionPoliticaId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     public long Votos { get; set; } | ||||||
|  |     public decimal VotosPorcentaje { get; set; } | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								Elecciones-Web/src/Elecciones.Database/Entities/Telegrama.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Elecciones-Web/src/Elecciones.Database/Entities/Telegrama.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  |  | ||||||
|  | // src/Elecciones.Database/Entities/Telegrama.cs | ||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Entities; | ||||||
|  |  | ||||||
|  | public class Telegrama | ||||||
|  | { | ||||||
|  |     // El ID único del telegrama (ej. "0202600060X") será nuestra Primary Key. | ||||||
|  |     [Key] | ||||||
|  |     public string Id { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     // En qué ámbito fue escrutado | ||||||
|  |     public int AmbitoGeograficoId { get; set; } | ||||||
|  |      | ||||||
|  |     // El contenido del telegrama en Base64 | ||||||
|  |     public string ContenidoBase64 { get; set; } = null!; | ||||||
|  |      | ||||||
|  |     public DateTime FechaEscaneo { get; set; } | ||||||
|  |     public DateTime FechaTotalizacion { get; set; } | ||||||
|  | } | ||||||
| @@ -12,8 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||||||
| namespace Elecciones.Database.Migrations | namespace Elecciones.Database.Migrations | ||||||
| { | { | ||||||
|     [DbContext(typeof(EleccionesDbContext))] |     [DbContext(typeof(EleccionesDbContext))] | ||||||
|     [Migration("20250814161142_InitialCreate")] |     [Migration("20250815181913_InitialSchema")] | ||||||
|     partial class InitialCreate |     partial class InitialSchema | ||||||
|     { |     { | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         protected override void BuildTargetModel(ModelBuilder modelBuilder) |         protected override void BuildTargetModel(ModelBuilder modelBuilder) | ||||||
| @@ -126,6 +126,63 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.ToTable("EstadosRecuentos"); |                     b.ToTable("EstadosRecuentos"); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuentoGeneral", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("CantidadElectores") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("CantidadVotantes") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("MesasEsperadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("MesasTotalizadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<decimal>("MesasTotalizadasPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<decimal>("ParticipacionPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  | 
 | ||||||
|  |                     b.HasKey("AmbitoGeograficoId"); | ||||||
|  | 
 | ||||||
|  |                     b.ToTable("EstadosRecuentosGenerales"); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  | 
 | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("NroBancas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  | 
 | ||||||
|  |                     b.HasIndex("AgrupacionPoliticaId"); | ||||||
|  | 
 | ||||||
|  |                     b.HasIndex("AmbitoGeograficoId"); | ||||||
|  | 
 | ||||||
|  |                     b.ToTable("ProyeccionesBancas"); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|                 { |                 { | ||||||
|                     b.Property<long>("Id") |                     b.Property<long>("Id") | ||||||
| @@ -154,6 +211,56 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.ToTable("ResultadosVotos"); |                     b.ToTable("ResultadosVotos"); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ResumenVoto", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  | 
 | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<long>("Votos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<decimal>("VotosPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  | 
 | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  | 
 | ||||||
|  |                     b.ToTable("ResumenesVotos"); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.Telegrama", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<string>("Id") | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<string>("ContenidoBase64") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<DateTime>("FechaEscaneo") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  | 
 | ||||||
|  |                     b.Property<DateTime>("FechaTotalizacion") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  | 
 | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  | 
 | ||||||
|  |                     b.ToTable("Telegramas"); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => | ||||||
|                 { |                 { | ||||||
|                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
| @@ -165,6 +272,25 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.Navigation("AmbitoGeografico"); |                     b.Navigation("AmbitoGeografico"); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AgrupacionPoliticaId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  | 
 | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AmbitoGeograficoId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  | 
 | ||||||
|  |                     b.Navigation("AgrupacionPolitica"); | ||||||
|  | 
 | ||||||
|  |                     b.Navigation("AmbitoGeografico"); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|                 { |                 { | ||||||
|                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
| @@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations; | |||||||
| namespace Elecciones.Database.Migrations | namespace Elecciones.Database.Migrations | ||||||
| { | { | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public partial class InitialCreate : Migration |     public partial class InitialSchema : Migration | ||||||
|     { |     { | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         protected override void Up(MigrationBuilder migrationBuilder) |         protected override void Up(MigrationBuilder migrationBuilder) | ||||||
| @@ -45,6 +45,54 @@ namespace Elecciones.Database.Migrations | |||||||
|                     table.PrimaryKey("PK_AmbitosGeograficos", x => x.Id); |                     table.PrimaryKey("PK_AmbitosGeograficos", x => x.Id); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "EstadosRecuentosGenerales", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     AmbitoGeograficoId = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     MesasEsperadas = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     MesasTotalizadas = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     MesasTotalizadasPorcentaje = table.Column<decimal>(type: "decimal(5,2)", precision: 5, scale: 2, nullable: false), | ||||||
|  |                     CantidadElectores = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     CantidadVotantes = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     ParticipacionPorcentaje = table.Column<decimal>(type: "decimal(5,2)", precision: 5, scale: 2, nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_EstadosRecuentosGenerales", x => x.AmbitoGeograficoId); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "ResumenesVotos", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<int>(type: "int", nullable: false) | ||||||
|  |                         .Annotation("SqlServer:Identity", "1, 1"), | ||||||
|  |                     AmbitoGeograficoId = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     AgrupacionPoliticaId = table.Column<string>(type: "nvarchar(max)", nullable: false), | ||||||
|  |                     Votos = table.Column<long>(type: "bigint", nullable: false), | ||||||
|  |                     VotosPorcentaje = table.Column<decimal>(type: "decimal(5,2)", precision: 5, scale: 2, nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_ResumenesVotos", x => x.Id); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "Telegramas", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<string>(type: "nvarchar(450)", nullable: false), | ||||||
|  |                     AmbitoGeograficoId = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     ContenidoBase64 = table.Column<string>(type: "nvarchar(max)", nullable: false), | ||||||
|  |                     FechaEscaneo = table.Column<DateTime>(type: "datetime2", nullable: false), | ||||||
|  |                     FechaTotalizacion = table.Column<DateTime>(type: "datetime2", nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_Telegramas", x => x.Id); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|             migrationBuilder.CreateTable( |             migrationBuilder.CreateTable( | ||||||
|                 name: "EstadosRecuentos", |                 name: "EstadosRecuentos", | ||||||
|                 columns: table => new |                 columns: table => new | ||||||
| @@ -72,6 +120,33 @@ namespace Elecciones.Database.Migrations | |||||||
|                         onDelete: ReferentialAction.Cascade); |                         onDelete: ReferentialAction.Cascade); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "ProyeccionesBancas", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<int>(type: "int", nullable: false) | ||||||
|  |                         .Annotation("SqlServer:Identity", "1, 1"), | ||||||
|  |                     AmbitoGeograficoId = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     AgrupacionPoliticaId = table.Column<string>(type: "nvarchar(450)", nullable: false), | ||||||
|  |                     NroBancas = table.Column<int>(type: "int", nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_ProyeccionesBancas", x => x.Id); | ||||||
|  |                     table.ForeignKey( | ||||||
|  |                         name: "FK_ProyeccionesBancas_AgrupacionesPoliticas_AgrupacionPoliticaId", | ||||||
|  |                         column: x => x.AgrupacionPoliticaId, | ||||||
|  |                         principalTable: "AgrupacionesPoliticas", | ||||||
|  |                         principalColumn: "Id", | ||||||
|  |                         onDelete: ReferentialAction.Cascade); | ||||||
|  |                     table.ForeignKey( | ||||||
|  |                         name: "FK_ProyeccionesBancas_AmbitosGeograficos_AmbitoGeograficoId", | ||||||
|  |                         column: x => x.AmbitoGeograficoId, | ||||||
|  |                         principalTable: "AmbitosGeograficos", | ||||||
|  |                         principalColumn: "Id", | ||||||
|  |                         onDelete: ReferentialAction.Cascade); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|             migrationBuilder.CreateTable( |             migrationBuilder.CreateTable( | ||||||
|                 name: "ResultadosVotos", |                 name: "ResultadosVotos", | ||||||
|                 columns: table => new |                 columns: table => new | ||||||
| @@ -99,6 +174,16 @@ namespace Elecciones.Database.Migrations | |||||||
|                         onDelete: ReferentialAction.Cascade); |                         onDelete: ReferentialAction.Cascade); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |             migrationBuilder.CreateIndex( | ||||||
|  |                 name: "IX_ProyeccionesBancas_AgrupacionPoliticaId", | ||||||
|  |                 table: "ProyeccionesBancas", | ||||||
|  |                 column: "AgrupacionPoliticaId"); | ||||||
|  | 
 | ||||||
|  |             migrationBuilder.CreateIndex( | ||||||
|  |                 name: "IX_ProyeccionesBancas_AmbitoGeograficoId", | ||||||
|  |                 table: "ProyeccionesBancas", | ||||||
|  |                 column: "AmbitoGeograficoId"); | ||||||
|  | 
 | ||||||
|             migrationBuilder.CreateIndex( |             migrationBuilder.CreateIndex( | ||||||
|                 name: "IX_ResultadosVotos_AgrupacionPoliticaId", |                 name: "IX_ResultadosVotos_AgrupacionPoliticaId", | ||||||
|                 table: "ResultadosVotos", |                 table: "ResultadosVotos", | ||||||
| @@ -117,9 +202,21 @@ namespace Elecciones.Database.Migrations | |||||||
|             migrationBuilder.DropTable( |             migrationBuilder.DropTable( | ||||||
|                 name: "EstadosRecuentos"); |                 name: "EstadosRecuentos"); | ||||||
| 
 | 
 | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "EstadosRecuentosGenerales"); | ||||||
|  | 
 | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "ProyeccionesBancas"); | ||||||
|  | 
 | ||||||
|             migrationBuilder.DropTable( |             migrationBuilder.DropTable( | ||||||
|                 name: "ResultadosVotos"); |                 name: "ResultadosVotos"); | ||||||
| 
 | 
 | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "ResumenesVotos"); | ||||||
|  | 
 | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "Telegramas"); | ||||||
|  | 
 | ||||||
|             migrationBuilder.DropTable( |             migrationBuilder.DropTable( | ||||||
|                 name: "AgrupacionesPoliticas"); |                 name: "AgrupacionesPoliticas"); | ||||||
| 
 | 
 | ||||||
							
								
								
									
										332
									
								
								Elecciones-Web/src/Elecciones.Database/Migrations/20250815183610_AddCategoriasElectorales.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								Elecciones-Web/src/Elecciones.Database/Migrations/20250815183610_AddCategoriasElectorales.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,332 @@ | |||||||
|  | // <auto-generated /> | ||||||
|  | using System; | ||||||
|  | using Elecciones.Database; | ||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.EntityFrameworkCore.Infrastructure; | ||||||
|  | using Microsoft.EntityFrameworkCore.Metadata; | ||||||
|  | using Microsoft.EntityFrameworkCore.Migrations; | ||||||
|  | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | ||||||
|  |  | ||||||
|  | #nullable disable | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Migrations | ||||||
|  | { | ||||||
|  |     [DbContext(typeof(EleccionesDbContext))] | ||||||
|  |     [Migration("20250815183610_AddCategoriasElectorales")] | ||||||
|  |     partial class AddCategoriasElectorales | ||||||
|  |     { | ||||||
|  |         /// <inheritdoc /> | ||||||
|  |         protected override void BuildTargetModel(ModelBuilder modelBuilder) | ||||||
|  |         { | ||||||
|  | #pragma warning disable 612, 618 | ||||||
|  |             modelBuilder | ||||||
|  |                 .HasAnnotation("ProductVersion", "9.0.8") | ||||||
|  |                 .HasAnnotation("Relational:MaxIdentifierLength", 128); | ||||||
|  |  | ||||||
|  |             SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.AgrupacionPolitica", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<string>("Id") | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("IdTelegrama") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Nombre") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("AgrupacionesPoliticas"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.AmbitoGeografico", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("CircuitoId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("DistritoId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("EstablecimientoId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("MesaId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("MunicipioId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("NivelId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Nombre") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("SeccionId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("SeccionProvincialId") | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("AmbitosGeograficos"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.CategoriaElectoral", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Nombre") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("Orden") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("CategoriasElectorales"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadElectores") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadVotantes") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime>("FechaTotalizacion") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasEsperadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasTotalizadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("MesasTotalizadasPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("ParticipacionPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("VotosEnBlanco") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("VotosNulos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("VotosRecurridos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("AmbitoGeograficoId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("EstadosRecuentos"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuentoGeneral", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadElectores") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadVotantes") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasEsperadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasTotalizadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("MesasTotalizadasPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("ParticipacionPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("AmbitoGeograficoId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("EstadosRecuentosGenerales"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("NroBancas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AgrupacionPoliticaId"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AmbitoGeograficoId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ProyeccionesBancas"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<long>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("CantidadVotos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AgrupacionPoliticaId"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AmbitoGeograficoId", "AgrupacionPoliticaId") | ||||||
|  |                         .IsUnique(); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ResultadosVotos"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ResumenVoto", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("Votos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("VotosPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ResumenesVotos"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.Telegrama", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<string>("Id") | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("ContenidoBase64") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime>("FechaEscaneo") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime>("FechaTotalizacion") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("Telegramas"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AmbitoGeograficoId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AmbitoGeografico"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AgrupacionPoliticaId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AmbitoGeograficoId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AgrupacionPolitica"); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AmbitoGeografico"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AgrupacionPoliticaId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AmbitoGeograficoId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AgrupacionPolitica"); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AmbitoGeografico"); | ||||||
|  |                 }); | ||||||
|  | #pragma warning restore 612, 618 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | using Microsoft.EntityFrameworkCore.Migrations; | ||||||
|  |  | ||||||
|  | #nullable disable | ||||||
|  |  | ||||||
|  | namespace Elecciones.Database.Migrations | ||||||
|  | { | ||||||
|  |     /// <inheritdoc /> | ||||||
|  |     public partial class AddCategoriasElectorales : Migration | ||||||
|  |     { | ||||||
|  |         /// <inheritdoc /> | ||||||
|  |         protected override void Up(MigrationBuilder migrationBuilder) | ||||||
|  |         { | ||||||
|  |             migrationBuilder.CreateTable( | ||||||
|  |                 name: "CategoriasElectorales", | ||||||
|  |                 columns: table => new | ||||||
|  |                 { | ||||||
|  |                     Id = table.Column<int>(type: "int", nullable: false), | ||||||
|  |                     Nombre = table.Column<string>(type: "nvarchar(max)", nullable: false), | ||||||
|  |                     Orden = table.Column<int>(type: "int", nullable: false) | ||||||
|  |                 }, | ||||||
|  |                 constraints: table => | ||||||
|  |                 { | ||||||
|  |                     table.PrimaryKey("PK_CategoriasElectorales", x => x.Id); | ||||||
|  |                 }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <inheritdoc /> | ||||||
|  |         protected override void Down(MigrationBuilder migrationBuilder) | ||||||
|  |         { | ||||||
|  |             migrationBuilder.DropTable( | ||||||
|  |                 name: "CategoriasElectorales"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -81,6 +81,23 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.ToTable("AmbitosGeograficos"); |                     b.ToTable("AmbitosGeograficos"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.CategoriaElectoral", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("Nombre") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("Orden") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("CategoriasElectorales"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => | ||||||
|                 { |                 { | ||||||
|                     b.Property<int>("AmbitoGeograficoId") |                     b.Property<int>("AmbitoGeograficoId") | ||||||
| @@ -123,6 +140,63 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.ToTable("EstadosRecuentos"); |                     b.ToTable("EstadosRecuentos"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuentoGeneral", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadElectores") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("CantidadVotantes") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasEsperadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("MesasTotalizadas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("MesasTotalizadasPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("ParticipacionPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("AmbitoGeograficoId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("EstadosRecuentosGenerales"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("NroBancas") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AgrupacionPoliticaId"); | ||||||
|  |  | ||||||
|  |                     b.HasIndex("AmbitoGeograficoId"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ProyeccionesBancas"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|                 { |                 { | ||||||
|                     b.Property<long>("Id") |                     b.Property<long>("Id") | ||||||
| @@ -151,6 +225,56 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.ToTable("ResultadosVotos"); |                     b.ToTable("ResultadosVotos"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ResumenVoto", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<int>("Id") | ||||||
|  |                         .ValueGeneratedOnAdd() | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id")); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("AgrupacionPoliticaId") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<long>("Votos") | ||||||
|  |                         .HasColumnType("bigint"); | ||||||
|  |  | ||||||
|  |                     b.Property<decimal>("VotosPorcentaje") | ||||||
|  |                         .HasPrecision(5, 2) | ||||||
|  |                         .HasColumnType("decimal(5,2)"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("ResumenesVotos"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.Telegrama", b => | ||||||
|  |                 { | ||||||
|  |                     b.Property<string>("Id") | ||||||
|  |                         .HasColumnType("nvarchar(450)"); | ||||||
|  |  | ||||||
|  |                     b.Property<int>("AmbitoGeograficoId") | ||||||
|  |                         .HasColumnType("int"); | ||||||
|  |  | ||||||
|  |                     b.Property<string>("ContenidoBase64") | ||||||
|  |                         .IsRequired() | ||||||
|  |                         .HasColumnType("nvarchar(max)"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime>("FechaEscaneo") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  |  | ||||||
|  |                     b.Property<DateTime>("FechaTotalizacion") | ||||||
|  |                         .HasColumnType("datetime2"); | ||||||
|  |  | ||||||
|  |                     b.HasKey("Id"); | ||||||
|  |  | ||||||
|  |                     b.ToTable("Telegramas"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => |             modelBuilder.Entity("Elecciones.Database.Entities.EstadoRecuento", b => | ||||||
|                 { |                 { | ||||||
|                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
| @@ -162,6 +286,25 @@ namespace Elecciones.Database.Migrations | |||||||
|                     b.Navigation("AmbitoGeografico"); |                     b.Navigation("AmbitoGeografico"); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |             modelBuilder.Entity("Elecciones.Database.Entities.ProyeccionBanca", b => | ||||||
|  |                 { | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AgrupacionPoliticaId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.HasOne("Elecciones.Database.Entities.AmbitoGeografico", "AmbitoGeografico") | ||||||
|  |                         .WithMany() | ||||||
|  |                         .HasForeignKey("AmbitoGeograficoId") | ||||||
|  |                         .OnDelete(DeleteBehavior.Cascade) | ||||||
|  |                         .IsRequired(); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AgrupacionPolitica"); | ||||||
|  |  | ||||||
|  |                     b.Navigation("AmbitoGeografico"); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => |             modelBuilder.Entity("Elecciones.Database.Entities.ResultadoVoto", b => | ||||||
|                 { |                 { | ||||||
|                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") |                     b.HasOne("Elecciones.Database.Entities.AgrupacionPolitica", "AgrupacionPolitica") | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | { | ||||||
|  |   "runtimeOptions": { | ||||||
|  |     "tfm": "net9.0", | ||||||
|  |     "framework": { | ||||||
|  |       "name": "Microsoft.NETCore.App", | ||||||
|  |       "version": "9.0.0" | ||||||
|  |     }, | ||||||
|  |     "configProperties": { | ||||||
|  |       "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, | ||||||
|  |       "System.Reflection.NullabilityInfoContext.IsSupported": true, | ||||||
|  |       "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b90baadeedb870b5b1c9eeeb7022a0d211b61bec")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | // <autogenerated /> | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // <auto-generated> | ||||||
|  | //     This code was generated by a tool. | ||||||
|  | // | ||||||
|  | //     Changes to this file may cause incorrect behavior and will be lost if | ||||||
|  | //     the code is regenerated. | ||||||
|  | // </auto-generated> | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | ||||||
|  | [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] | ||||||
|  | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
|  | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
|  | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | ||||||
|  | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | ||||||
|  | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|  |  | ||||||
|  | // Generado por la clase WriteCodeFragment de MSBuild. | ||||||
|  |  | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | is_global = true | ||||||
|  | build_property.TargetFramework = net9.0 | ||||||
|  | build_property.TargetFramework = net9.0 | ||||||
|  | build_property.TargetPlatformMinVersion =  | ||||||
|  | build_property.TargetPlatformMinVersion =  | ||||||
|  | build_property.UsingMicrosoftNETSdkWeb =  | ||||||
|  | build_property.UsingMicrosoftNETSdkWeb =  | ||||||
|  | build_property.ProjectTypeGuids =  | ||||||
|  | build_property.ProjectTypeGuids =  | ||||||
|  | build_property.InvariantGlobalization =  | ||||||
|  | build_property.InvariantGlobalization =  | ||||||
|  | build_property.PlatformNeutralAssembly =  | ||||||
|  | build_property.PlatformNeutralAssembly =  | ||||||
|  | build_property.EnforceExtendedAnalyzerRules =  | ||||||
|  | build_property.EnforceExtendedAnalyzerRules =  | ||||||
|  | build_property._SupportedPlatformList = Linux,macOS,Windows | ||||||
|  | build_property._SupportedPlatformList = Linux,macOS,Windows | ||||||
|  | build_property.RootNamespace = Elecciones.Database | ||||||
|  | build_property.ProjectDir = E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\ | ||||||
|  | build_property.EnableComHosting =  | ||||||
|  | build_property.EnableGeneratedComInterfaceComImportInterop =  | ||||||
|  | build_property.EffectiveAnalysisLevelStyle = 9.0 | ||||||
|  | build_property.EnableCodeStyleSeverity =  | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | // <auto-generated/> | ||||||
|  | global using global::System; | ||||||
|  | global using global::System.Collections.Generic; | ||||||
|  | global using global::System.IO; | ||||||
|  | global using global::System.Linq; | ||||||
|  | global using global::System.Net.Http; | ||||||
|  | global using global::System.Threading; | ||||||
|  | global using global::System.Threading.Tasks; | ||||||
| @@ -0,0 +1,14 @@ | |||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\bin\Release\net9.0\Elecciones.Database.deps.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\bin\Release\net9.0\Elecciones.Database.runtimeconfig.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\bin\Release\net9.0\Elecciones.Database.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\bin\Release\net9.0\Elecciones.Database.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.csproj.AssemblyReference.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.GeneratedMSBuildEditorConfig.editorconfig | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.AssemblyInfoInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.AssemblyInfo.cs | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.csproj.CoreCompileInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\refint\Elecciones.Database.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\Elecciones.Database.genruntimeconfig.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Database\obj\Release\net9.0\ref\Elecciones.Database.dll | ||||||
| @@ -9,6 +9,12 @@ | |||||||
|     <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" /> |     <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <None Update="buenos-aires-municipios.geojson"> | ||||||
|  |       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||||
|  |     </None> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|   <PropertyGroup> |   <PropertyGroup> | ||||||
|     <TargetFramework>net9.0</TargetFramework> |     <TargetFramework>net9.0</TargetFramework> | ||||||
|     <ImplicitUsings>enable</ImplicitUsings> |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ using System.Collections.Generic; | |||||||
| using System.Net.Http; | using System.Net.Http; | ||||||
| using System.Net.Http.Json; | using System.Net.Http.Json; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
|  | using static Elecciones.Core.DTOs.BancaDto; | ||||||
|  |  | ||||||
| namespace Elecciones.Infrastructure.Services; | namespace Elecciones.Infrastructure.Services; | ||||||
|  |  | ||||||
| @@ -18,6 +19,8 @@ public class ElectoralApiService : IElectoralApiService | |||||||
|         _configuration = configuration; |         _configuration = configuration; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // --- MÉTODOS DE LA INTERFAZ --- | ||||||
|  |  | ||||||
|     public async Task<string?> GetAuthTokenAsync() |     public async Task<string?> GetAuthTokenAsync() | ||||||
|     { |     { | ||||||
|         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
| @@ -67,20 +70,84 @@ public class ElectoralApiService : IElectoralApiService | |||||||
|     public async Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) |     public async Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) | ||||||
|     { |     { | ||||||
|         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |  | ||||||
|         // Construimos la URL con todos los parámetros requeridos. Usamos categoría 5 (Diputados) como ejemplo. |  | ||||||
|         var requestUri = $"/api/resultados/getResultados?distritold={distritoId}&seccionld={seccionId}&municipiold={municipioId}&categoriald=5"; |         var requestUri = $"/api/resultados/getResultados?distritold={distritoId}&seccionld={seccionId}&municipiold={municipioId}&categoriald=5"; | ||||||
|  |  | ||||||
|         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|         request.Headers.Add("Authorization", $"Bearer {authToken}"); |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |  | ||||||
|         var response = await client.SendAsync(request); |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode | ||||||
|  |             ? await response.Content.ReadFromJsonAsync<ResultadosDto>() | ||||||
|  |             : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|         if (!response.IsSuccessStatusCode) |     public async Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId) | ||||||
|     { |     { | ||||||
|             return null; |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var requestUri = $"/api/resultados/getBancas?distritold={distritoId}&seccionld={seccionId}&categoriald=5"; | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |  | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode | ||||||
|  |             ? await response.Content.ReadFromJsonAsync<RepartoBancasDto>() | ||||||
|  |             : null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|         return await response.Content.ReadFromJsonAsync<ResultadosDto>(); |     public async Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) | ||||||
|  |     { | ||||||
|  |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var requestUri = $"/api/resultados/getTelegramasTotalizados?distritold={distritoId}&seccionld={seccionId}"; | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |  | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode | ||||||
|  |             ? await response.Content.ReadFromJsonAsync<List<string[]>>() | ||||||
|  |             : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) | ||||||
|  |     { | ||||||
|  |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var requestUri = $"/api/resultados/getFile?mesald={mesaId}"; | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |  | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode | ||||||
|  |             ? await response.Content.ReadFromJsonAsync<TelegramaFileDto>() | ||||||
|  |             : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) | ||||||
|  |     { | ||||||
|  |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var requestUri = $"/api/resultados/getResumen?distritold={distritoId}"; | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<ResumenDto>() : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) | ||||||
|  |     { | ||||||
|  |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var requestUri = $"/api/estados/estadoRecuento?distritold={distritoId}"; | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, requestUri); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<EstadoRecuentoGeneralDto>() : null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) | ||||||
|  |     { | ||||||
|  |         var client = _httpClientFactory.CreateClient("ElectoralApiClient"); | ||||||
|  |         var request = new HttpRequestMessage(HttpMethod.Get, "/api/catalogo/getCategorias"); | ||||||
|  |         request.Headers.Add("Authorization", $"Bearer {authToken}"); | ||||||
|  |         var response = await client.SendAsync(request); | ||||||
|  |         return response.IsSuccessStatusCode | ||||||
|  |             ? await response.Content.ReadFromJsonAsync<List<CategoriaDto>>() | ||||||
|  |             : null; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -1,101 +1,145 @@ | |||||||
| // src/Elecciones.Infrastructure/Services/FakeElectoralApiService.cs |  | ||||||
| using Elecciones.Core.DTOs; | using Elecciones.Core.DTOs; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.IO; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text.Json; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using static Elecciones.Core.DTOs.BancaDto; | ||||||
|  |  | ||||||
| namespace Elecciones.Infrastructure.Services; | namespace Elecciones.Infrastructure.Services; | ||||||
|  |  | ||||||
| public class FakeElectoralApiService : IElectoralApiService | public class FakeElectoralApiService : IElectoralApiService | ||||||
| { | { | ||||||
|     private readonly ILogger<FakeElectoralApiService> _logger; |     private readonly ILogger<FakeElectoralApiService> _logger; | ||||||
|  |     private List<AmbitoDto>? _fakeAmbitosCache = null; | ||||||
|  |     private readonly Random _random = new Random(); | ||||||
|  |  | ||||||
|     public FakeElectoralApiService(ILogger<FakeElectoralApiService> logger) |     public FakeElectoralApiService(ILogger<FakeElectoralApiService> logger) | ||||||
|     { |     { | ||||||
|         _logger = logger; |         _logger = logger; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private void GenerateFakeAmbitosFromGeoJson() | ||||||
|  |     { | ||||||
|  |         if (_fakeAmbitosCache != null) return; | ||||||
|  |         _logger.LogWarning("--- USANDO SERVICIO FALSO (FAKE) ---"); | ||||||
|  |         _logger.LogInformation("Generando datos de prueba de ámbitos desde el archivo GeoJSON..."); | ||||||
|  |  | ||||||
|  |         var geoJsonPath = Path.Combine(AppContext.BaseDirectory, "buenos-aires-municipios.geojson"); | ||||||
|  |         if (!File.Exists(geoJsonPath)) | ||||||
|  |         { | ||||||
|  |             _logger.LogError("No se encontró el archivo buenos-aires-municipios.geojson."); | ||||||
|  |             _fakeAmbitosCache = new List<AmbitoDto>(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var geoJsonString = File.ReadAllText(geoJsonPath); | ||||||
|  |         using var document = JsonDocument.Parse(geoJsonString); | ||||||
|  |         var features = document.RootElement.GetProperty("features").EnumerateArray().ToList(); | ||||||
|  |  | ||||||
|  |         var ambitos = new List<AmbitoDto>(); | ||||||
|  |         ambitos.Add(new AmbitoDto { NivelId = 10, Nombre = "BUENOS AIRES", CodigoAmbitos = new CodigoAmbitoDto { DistritoId = "02" } }); | ||||||
|  |         var secciones = new List<AmbitoDto> { | ||||||
|  |             new() { NivelId = 4, Nombre = "PRIMERA SECCION ELECTORAL", CodigoAmbitos = new CodigoAmbitoDto { DistritoId = "02", SeccionId = "0001" } }, | ||||||
|  |             new() { NivelId = 4, Nombre = "SEGUNDA SECCION ELECTORAL", CodigoAmbitos = new CodigoAmbitoDto { DistritoId = "02", SeccionId = "0002" } }, | ||||||
|  |             new() { NivelId = 4, Nombre = "TERCERA SECCION ELECTORAL", CodigoAmbitos = new CodigoAmbitoDto { DistritoId = "02", SeccionId = "0003" } } | ||||||
|  |         }; | ||||||
|  |         ambitos.AddRange(secciones); | ||||||
|  |  | ||||||
|  |         for (int i = 0; i < features.Count; i++) | ||||||
|  |         { | ||||||
|  |             var feature = features[i]; | ||||||
|  |             var properties = feature.GetProperty("properties"); | ||||||
|  |             var seccionAsignada = secciones[i % secciones.Count]; | ||||||
|  |             ambitos.Add(new AmbitoDto { NivelId = 5, Nombre = properties.GetProperty("nam").GetString() ?? "Sin Nombre", CodigoAmbitos = new CodigoAmbitoDto { MunicipioId = properties.GetProperty("cca").GetString(), DistritoId = "02", SeccionId = seccionAsignada.CodigoAmbitos.SeccionId } }); | ||||||
|  |         } | ||||||
|  |         _fakeAmbitosCache = ambitos; | ||||||
|  |         _logger.LogInformation("Se generaron {count} ámbitos de prueba (Provincia, Secciones y Municipios).", _fakeAmbitosCache.Count); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) | ||||||
|  |     { | ||||||
|  |         _logger.LogInformation("Simulando obtención de Resumen para distrito {DistritoId}...", distritoId); | ||||||
|  |         var resumen = new ResumenDto | ||||||
|  |         { | ||||||
|  |             ValoresTotalizadosPositivos = new List<ResumenPositivoDto> | ||||||
|  |         { | ||||||
|  |             new() { IdAgrupacion = "025", Votos = 2500000 + _random.Next(1000), VotosPorcentaje = 45.12m }, | ||||||
|  |             new() { IdAgrupacion = "018", Votos = 2100000 + _random.Next(1000), VotosPorcentaje = 38.78m }, | ||||||
|  |             new() { IdAgrupacion = "031", Votos = 800000 + _random.Next(1000), VotosPorcentaje = 14.10m } | ||||||
|  |         } | ||||||
|  |         }; | ||||||
|  |         return Task.FromResult<ResumenDto?>(resumen); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) | ||||||
|  |     { | ||||||
|  |         _logger.LogInformation("Simulando obtención de Estado de Recuento General para distrito {DistritoId}...", distritoId); | ||||||
|  |         var estado = new EstadoRecuentoGeneralDto | ||||||
|  |         { | ||||||
|  |             MesasEsperadas = 38000, | ||||||
|  |             MesasTotalizadas = _random.Next(28000, 37000), | ||||||
|  |             MesasTotalizadasPorcentaje = 95.5m, | ||||||
|  |             CantidadElectores = 12500000, | ||||||
|  |             CantidadVotantes = 9375000, | ||||||
|  |             ParticipacionPorcentaje = 75.0m | ||||||
|  |         }; | ||||||
|  |         return Task.FromResult<EstadoRecuentoGeneralDto?>(estado); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public Task<string?> GetAuthTokenAsync() |     public Task<string?> GetAuthTokenAsync() | ||||||
|     { |     { | ||||||
|         _logger.LogWarning("--- USANDO SERVICIO FALSO (FAKE) ---"); |  | ||||||
|         _logger.LogInformation("Simulando obtención de token..."); |         _logger.LogInformation("Simulando obtención de token..."); | ||||||
|         string fakeToken = "FAKE_TOKEN_FOR_DEVELOPMENT"; |         return Task.FromResult<string?>("FAKE_TOKEN_FOR_DEVELOPMENT"); | ||||||
|         return Task.FromResult<string?>(fakeToken); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) |     public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) | ||||||
|     { |     { | ||||||
|         _logger.LogInformation("Simulando obtención de Catálogo Completo..."); |         GenerateFakeAmbitosFromGeoJson(); | ||||||
|  |         var catalogo = new List<CatalogoDto> { new() { Version = 1, CategoriaId = 5, Ambitos = _fakeAmbitosCache ?? new List<AmbitoDto>(), Niveles = new List<NivelDto> { new() { NivelId = 10, Nombre = "Provincia" }, new() { NivelId = 4, Nombre = "Seccion" }, new() { NivelId = 5, Nombre = "Municipio" } } } }; | ||||||
|         var catalogo = new List<CatalogoDto> |  | ||||||
|         { |  | ||||||
|             new() // Simulamos el catálogo para la categoría de Diputados (ID 5) |  | ||||||
|             { |  | ||||||
|                 Version = 1, |  | ||||||
|                 CategoriaId = 5, |  | ||||||
|                 Ambitos = |  | ||||||
|                 [ |  | ||||||
|                     new() { NivelId = 10, Nombre = "BUENOS AIRES", CodigoAmbitos = new() { DistritoId = "02" } }, |  | ||||||
|                     new() { NivelId = 5, Nombre = "LA PLATA", CodigoAmbitos = new() { DistritoId = "02", SeccionId = "0001", MunicipioId = "056" } }, |  | ||||||
|                     new() { NivelId = 5, Nombre = "MAR DEL PLATA", CodigoAmbitos = new() { DistritoId = "02", SeccionId = "0005", MunicipioId = "035" } } |  | ||||||
|                 ], |  | ||||||
|                 Niveles = |  | ||||||
|                 [ |  | ||||||
|                     new() { NivelId = 10, Nombre = "Provincia" }, |  | ||||||
|                     new() { NivelId = 5, Nombre = "Municipio" } |  | ||||||
|                 ] |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         return Task.FromResult<List<CatalogoDto>?>(catalogo); |         return Task.FromResult<List<CatalogoDto>?>(catalogo); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId) |     public Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId) | ||||||
|     { |     { | ||||||
|         _logger.LogInformation("Simulando obtención de Agrupaciones Políticas para el distrito {Distrito} y categoría {Categoria}...", distritoId, categoriaId); |         var agrupaciones = new List<AgrupacionDto> { new() { IdAgrupacion = "018", IdAgrupacionTelegrama = "131", NombreAgrupacion = "FRENTE DE AVANZADA" }, new() { IdAgrupacion = "025", IdAgrupacionTelegrama = "132", NombreAgrupacion = "ALIANZA POR EL FUTURO" }, new() { IdAgrupacion = "031", IdAgrupacionTelegrama = "133", NombreAgrupacion = "UNION POPULAR" }, new() { IdAgrupacion = "045", IdAgrupacionTelegrama = "134", NombreAgrupacion = "PARTIDO VECINALISTA" } }; | ||||||
|  |  | ||||||
|         var agrupaciones = new List<AgrupacionDto> |  | ||||||
|     { |  | ||||||
|         new() { IdAgrupacion = "018", IdAgrupacionTelegrama = "131", NombreAgrupacion = "FRENTE DE AVANZADA" }, |  | ||||||
|         new() { IdAgrupacion = "025", IdAgrupacionTelegrama = "132", NombreAgrupacion = "ALIANZA POR EL FUTURO" }, |  | ||||||
|         new() { IdAgrupacion = "031", IdAgrupacionTelegrama = "133", NombreAgrupacion = "UNION POPULAR" }, |  | ||||||
|         new() { IdAgrupacion = "045", IdAgrupacionTelegrama = "134", NombreAgrupacion = "PARTIDO VECINALISTA" } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|         return Task.FromResult<List<AgrupacionDto>?>(agrupaciones); |         return Task.FromResult<List<AgrupacionDto>?>(agrupaciones); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) |     public Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) | ||||||
|     { |     { | ||||||
|         _logger.LogInformation("Simulando obtención de Resultados para el municipio {MunicipioId}...", municipioId); |         var resultados = new ResultadosDto { FechaTotalizacion = DateTime.Now.ToString("o"), EstadoRecuento = new EstadoRecuentoDto { MesasEsperadas = _random.Next(100, 2000), MesasTotalizadas = _random.Next(50, 100), CantidadElectores = _random.Next(50000, 600000), ParticipacionPorcentaje = _random.Next(60, 85) + (decimal)_random.NextDouble() }, ValoresTotalizadosPositivos = new List<VotosPositivosDto> { new() { IdAgrupacion = "018", Votos = _random.Next(10000, 20000) }, new() { IdAgrupacion = "025", Votos = _random.Next(15000, 25000) }, new() { IdAgrupacion = "031", Votos = _random.Next(5000, 10000) }, new() { IdAgrupacion = "045", Votos = _random.Next(2000, 5000) } }, ValoresTotalizadosOtros = new VotosOtrosDto { VotosEnBlanco = _random.Next(1000, 2000), VotosNulos = _random.Next(500, 1000), VotosRecurridos = _random.Next(20, 50) } }; | ||||||
|  |  | ||||||
|         // YA NO FILTRAMOS POR ID. DEVOLVEMOS DATOS SIMULADOS PARA CUALQUIER MUNICIPIO. |  | ||||||
|  |  | ||||||
|         var random = new Random(); |  | ||||||
|         var resultados = new ResultadosDto |  | ||||||
|         { |  | ||||||
|             FechaTotalizacion = DateTime.Now.ToString("o"), |  | ||||||
|             EstadoRecuento = new EstadoRecuentoDto |  | ||||||
|             { |  | ||||||
|                 MesasEsperadas = random.Next(100, 2000), // Hacemos que varíe |  | ||||||
|                 MesasTotalizadas = random.Next(50, 100), |  | ||||||
|                 CantidadElectores = random.Next(50000, 600000), |  | ||||||
|                 ParticipacionPorcentaje = random.Next(60, 85) + (decimal)random.NextDouble() |  | ||||||
|             }, |  | ||||||
|             ValoresTotalizadosPositivos = |  | ||||||
|             [ |  | ||||||
|                 // Usamos los IDs reales de nuestro catálogo de agrupaciones falsas |  | ||||||
|                 new() { IdAgrupacion = "018", NombreAgrupacion = "FRENTE DE AVANZADA", Votos = random.Next(10000, 20000) }, |  | ||||||
|             new() { IdAgrupacion = "025", NombreAgrupacion = "ALIANZA POR EL FUTURO", Votos = random.Next(15000, 25000) }, |  | ||||||
|             new() { IdAgrupacion = "031", NombreAgrupacion = "UNION POPULAR", Votos = random.Next(5000, 10000) }, |  | ||||||
|             new() { IdAgrupacion = "045", NombreAgrupacion = "PARTIDO VECINALISTA", Votos = random.Next(2000, 5000) } |  | ||||||
|             ], |  | ||||||
|             ValoresTotalizadosOtros = new VotosOtrosDto |  | ||||||
|             { |  | ||||||
|                 VotosEnBlanco = random.Next(1000, 2000), |  | ||||||
|                 VotosNulos = random.Next(500, 1000), |  | ||||||
|                 VotosRecurridos = random.Next(20, 50) |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         return Task.FromResult<ResultadosDto?>(resultados); |         return Task.FromResult<ResultadosDto?>(resultados); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId) | ||||||
|  |     { | ||||||
|  |         var reparto = new RepartoBancasDto { RepartoBancas = new List<BancaDto> { new() { IdAgrupacion = "025", NroBancas = _random.Next(5, 9) }, new() { IdAgrupacion = "018", NroBancas = _random.Next(3, 7) } } }; | ||||||
|  |         return Task.FromResult<RepartoBancasDto?>(reparto); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) | ||||||
|  |     { | ||||||
|  |         var lista = new List<string[]> { new[] { $"02{seccionId}0001M" }, new[] { $"02{seccionId}0002M" } }; | ||||||
|  |         return Task.FromResult<List<string[]>?>(lista); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) | ||||||
|  |     { | ||||||
|  |         var file = new TelegramaFileDto { NombreArchivo = mesaId, Imagen = "FAKE_BASE64_PDF_CONTENT", FechaEscaneo = DateTime.UtcNow.AddMinutes(-10).ToString("o"), FechaTotalizacion = DateTime.UtcNow.ToString("o") }; | ||||||
|  |         return Task.FromResult<TelegramaFileDto?>(file); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) | ||||||
|  |     { | ||||||
|  |         _logger.LogInformation("Simulando obtención de Categorías Electorales..."); | ||||||
|  |         var categorias = new List<CategoriaDto> | ||||||
|  |     { | ||||||
|  |         new() { CategoriaId = 5, Nombre = "DIPUTADOS NACIONALES", Orden = 1 }, | ||||||
|  |         new() { CategoriaId = 6, Nombre = "SENADORES NACIONALES", Orden = 2 } | ||||||
|  |     }; | ||||||
|  |         return Task.FromResult<List<CategoriaDto>?>(categorias); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -1,12 +1,24 @@ | |||||||
| // src/Elecciones.Infrastructure/Services/IElectoralApiService.cs |  | ||||||
| using Elecciones.Core.DTOs; | using Elecciones.Core.DTOs; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using static Elecciones.Core.DTOs.BancaDto; | ||||||
|  |  | ||||||
| namespace Elecciones.Infrastructure.Services; | namespace Elecciones.Infrastructure.Services; | ||||||
|  |  | ||||||
| public interface IElectoralApiService | public interface IElectoralApiService | ||||||
| { | { | ||||||
|     Task<string?> GetAuthTokenAsync(); |     Task<string?> GetAuthTokenAsync(); | ||||||
|  |  | ||||||
|  |     // Métodos para catálogos | ||||||
|     Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken); |     Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken); | ||||||
|     Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId); |     Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId); | ||||||
|  |  | ||||||
|  |     // Métodos para resultados y datos dinámicos | ||||||
|     Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId); |     Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId); | ||||||
|  |     Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId); | ||||||
|  |     Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId); | ||||||
|  |     Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId); | ||||||
|  |     Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId); | ||||||
|  |     Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId); | ||||||
|  |     Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken); | ||||||
| } | } | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -0,0 +1,285 @@ | |||||||
|  | { | ||||||
|  |   "runtimeTarget": { | ||||||
|  |     "name": ".NETCoreApp,Version=v9.0", | ||||||
|  |     "signature": "" | ||||||
|  |   }, | ||||||
|  |   "compilationOptions": {}, | ||||||
|  |   "targets": { | ||||||
|  |     ".NETCoreApp,Version=v9.0": { | ||||||
|  |       "Elecciones.Infrastructure/1.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Elecciones.Core": "1.0.0", | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Http": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "Elecciones.Infrastructure.dll": {} | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Configuration/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Primitives": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Configuration.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Configuration.Abstractions/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Primitives": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Configuration.Abstractions.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Configuration.Binder/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.DependencyInjection/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.DependencyInjection.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.DependencyInjection.Abstractions/9.0.8": { | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Diagnostics/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Diagnostics.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Diagnostics.Abstractions/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Options": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Diagnostics.Abstractions.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Http/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Diagnostics": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Logging": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Logging.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Options": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Http.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Logging/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Logging.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Options": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Logging.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Logging.Abstractions/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Logging.Abstractions.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Options/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Primitives": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Options.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Options.ConfigurationExtensions/9.0.8": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Configuration.Binder": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Options": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Primitives": "9.0.8" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Microsoft.Extensions.Primitives/9.0.8": { | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.Primitives.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.825.36511" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Elecciones.Core/1.0.0": { | ||||||
|  |         "runtime": { | ||||||
|  |           "Elecciones.Core.dll": { | ||||||
|  |             "assemblyVersion": "1.0.0.0", | ||||||
|  |             "fileVersion": "1.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "libraries": { | ||||||
|  |     "Elecciones.Infrastructure/1.0.0": { | ||||||
|  |       "type": "project", | ||||||
|  |       "serviceable": false, | ||||||
|  |       "sha512": "" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Configuration/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-6m+8Xgmf8UWL0p/oGqBM+0KbHE5/ePXbV1hKXgC59zEv0aa0DW5oiiyxDbK5kH5j4gIvyD5uWL0+HadKBJngvQ==", | ||||||
|  |       "path": "microsoft.extensions.configuration/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.configuration.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Configuration.Abstractions/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-yNou2KM35RvzOh4vUFtl2l33rWPvOCoba+nzEDJ+BgD8aOL/jew4WPCibQvntRfOJ2pJU8ARygSMD+pdjvDHuA==", | ||||||
|  |       "path": "microsoft.extensions.configuration.abstractions/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.configuration.abstractions.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Configuration.Binder/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-0vK9DnYrYChdiH3yRZWkkp4x4LbrfkWEdBc5HOsQ8t/0CLOWKXKkkhOE8A1shlex0hGydbGrhObeypxz/QTm+w==", | ||||||
|  |       "path": "microsoft.extensions.configuration.binder/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.configuration.binder.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.DependencyInjection/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==", | ||||||
|  |       "path": "microsoft.extensions.dependencyinjection/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.dependencyinjection.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.DependencyInjection.Abstractions/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw==", | ||||||
|  |       "path": "microsoft.extensions.dependencyinjection.abstractions/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Diagnostics/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-BKkLCFXzJvNmdngeYBf72VXoZqTJSb1orvjdzDLaGobicoGFBPW8ug2ru1nnEewMEwJzMgnsjHQY8EaKWmVhKg==", | ||||||
|  |       "path": "microsoft.extensions.diagnostics/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.diagnostics.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Diagnostics.Abstractions/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-UDY7blv4DCyIJ/8CkNrQKLaAZFypXQavRZ2DWf/2zi1mxYYKKw2t8AOCBWxNntyPZHPGhtEmL3snFM98ADZqTw==", | ||||||
|  |       "path": "microsoft.extensions.diagnostics.abstractions/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.diagnostics.abstractions.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Http/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-jDj+4aDByk47oESlDDTtk6LWzlXlmoCsjCn6ihd+i9OntN885aPLszUII5+w0B/7wYSZcS3KdjqLAIhKLSiBXQ==", | ||||||
|  |       "path": "microsoft.extensions.http/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.http.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Logging/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==", | ||||||
|  |       "path": "microsoft.extensions.logging/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.logging.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Logging.Abstractions/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==", | ||||||
|  |       "path": "microsoft.extensions.logging.abstractions/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.logging.abstractions.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Options/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==", | ||||||
|  |       "path": "microsoft.extensions.options/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.options.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Options.ConfigurationExtensions/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-eW2s6n06x0w6w4nsX+SvpgsFYkl+Y0CttYAt6DKUXeqprX+hzNqjSfOh637fwNJBg7wRBrOIRHe49gKiTgJxzQ==", | ||||||
|  |       "path": "microsoft.extensions.options.configurationextensions/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.options.configurationextensions.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Microsoft.Extensions.Primitives/9.0.8": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug==", | ||||||
|  |       "path": "microsoft.extensions.primitives/9.0.8", | ||||||
|  |       "hashPath": "microsoft.extensions.primitives.9.0.8.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Elecciones.Core/1.0.0": { | ||||||
|  |       "type": "project", | ||||||
|  |       "serviceable": false, | ||||||
|  |       "sha512": "" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b90baadeedb870b5b1c9eeeb7022a0d211b61bec")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -13,3 +13,4 @@ E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0 | |||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\refint\Elecciones.Infrastructure.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\refint\Elecciones.Infrastructure.dll | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\Elecciones.Infrastructure.pdb | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\Elecciones.Infrastructure.pdb | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\ref\Elecciones.Infrastructure.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Debug\net9.0\ref\Elecciones.Infrastructure.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Debug\net9.0\buenos-aires-municipios.geojson | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | // <autogenerated /> | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // <auto-generated> | ||||||
|  | //     This code was generated by a tool. | ||||||
|  | // | ||||||
|  | //     Changes to this file may cause incorrect behavior and will be lost if | ||||||
|  | //     the code is regenerated. | ||||||
|  | // </auto-generated> | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | ||||||
|  | [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] | ||||||
|  | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
|  | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
|  | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | ||||||
|  | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | ||||||
|  | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|  |  | ||||||
|  | // Generado por la clase WriteCodeFragment de MSBuild. | ||||||
|  |  | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | is_global = true | ||||||
|  | build_property.TargetFramework = net9.0 | ||||||
|  | build_property.TargetPlatformMinVersion =  | ||||||
|  | build_property.UsingMicrosoftNETSdkWeb =  | ||||||
|  | build_property.ProjectTypeGuids =  | ||||||
|  | build_property.InvariantGlobalization =  | ||||||
|  | build_property.PlatformNeutralAssembly =  | ||||||
|  | build_property.EnforceExtendedAnalyzerRules =  | ||||||
|  | build_property._SupportedPlatformList = Linux,macOS,Windows | ||||||
|  | build_property.RootNamespace = Elecciones.Infrastructure | ||||||
|  | build_property.ProjectDir = E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\ | ||||||
|  | build_property.EnableComHosting =  | ||||||
|  | build_property.EnableGeneratedComInterfaceComImportInterop =  | ||||||
|  | build_property.EffectiveAnalysisLevelStyle = 9.0 | ||||||
|  | build_property.EnableCodeStyleSeverity =  | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | // <auto-generated/> | ||||||
|  | global using global::System; | ||||||
|  | global using global::System.Collections.Generic; | ||||||
|  | global using global::System.IO; | ||||||
|  | global using global::System.Linq; | ||||||
|  | global using global::System.Net.Http; | ||||||
|  | global using global::System.Threading; | ||||||
|  | global using global::System.Threading.Tasks; | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\buenos-aires-municipios.geojson | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\Elecciones.Infrastructure.deps.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\Elecciones.Infrastructure.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\Elecciones.Infrastructure.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\Elecciones.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\bin\Release\net9.0\Elecciones.Core.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.csproj.AssemblyReference.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.GeneratedMSBuildEditorConfig.editorconfig | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.AssemblyInfoInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.AssemblyInfo.cs | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.csproj.CoreCompileInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Eleccion.B7F7B2EF.Up2Date | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\refint\Elecciones.Infrastructure.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\Elecciones.Infrastructure.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Infrastructure\obj\Release\net9.0\ref\Elecciones.Infrastructure.dll | ||||||
| @@ -11,6 +11,10 @@ | |||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.8" /> |     <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.8" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.5" /> |     <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.5" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" /> |     <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" /> | ||||||
|  |     <PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" /> | ||||||
|  |     <PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" /> | ||||||
|  |     <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> | ||||||
|  |     <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|   | |||||||
| @@ -2,23 +2,37 @@ using Elecciones.Database; | |||||||
| using Elecciones.Infrastructure.Services; | using Elecciones.Infrastructure.Services; | ||||||
| using Elecciones.Worker; | using Elecciones.Worker; | ||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.Extensions.DependencyInjection; | ||||||
|  | using Microsoft.Extensions.Hosting; | ||||||
|  | using Serilog; | ||||||
|  | using System.Net.Http; | ||||||
|  | using System.Net.Security; | ||||||
|  | using System.Security.Authentication; | ||||||
|  |  | ||||||
|  | Log.Logger = new LoggerConfiguration() | ||||||
|  |     .WriteTo.Console() | ||||||
|  |     .CreateBootstrapLogger(); | ||||||
|  |  | ||||||
|  | Log.Information("Iniciando Elecciones.Worker Host..."); | ||||||
|  |  | ||||||
| var builder = Host.CreateApplicationBuilder(args); | var builder = Host.CreateApplicationBuilder(args); | ||||||
|  |  | ||||||
| // --- Configuración de Servicios --- | builder.Services.AddSerilog(config =>  | ||||||
|  |     config | ||||||
|  |         .ReadFrom.Configuration(builder.Configuration) | ||||||
|  |         .Enrich.FromLogContext() | ||||||
|  |         .WriteTo.Console() | ||||||
|  |         .WriteTo.File("logs/worker-.log", rollingInterval: RollingInterval.Day)); | ||||||
|  |  | ||||||
| // 1. Configuración de Base de Datos (¡Este bloque es esencial!) | // --- Configuración de Servicios --- | ||||||
| var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); | var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); | ||||||
| builder.Services.AddDbContext<EleccionesDbContext>(options => | builder.Services.AddDbContext<EleccionesDbContext>(options => | ||||||
|     options.UseSqlServer(connectionString)); |     options.UseSqlServer(connectionString)); | ||||||
|  |  | ||||||
| // 2. Configuración del Servicio de API (elegirá el Real o el Falso según el modo de compilación) |  | ||||||
| #if DEBUG | #if DEBUG | ||||||
| // En modo DEBUG (desarrollo local), usamos el servicio FALSO. |  | ||||||
| // No es necesario registrar el ILogger, .NET lo inyecta automáticamente. |  | ||||||
| builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>(); | builder.Services.AddSingleton<IElectoralApiService, FakeElectoralApiService>(); | ||||||
| #else | #else | ||||||
| // En modo RELEASE (producción), usamos el servicio REAL. | // --- SECCIÓN MODIFICADA (FINAL) --- | ||||||
| builder.Services.AddHttpClient("ElectoralApiClient", client => | builder.Services.AddHttpClient("ElectoralApiClient", client => | ||||||
| { | { | ||||||
|     var baseUrl = builder.Configuration["ElectoralApi:BaseUrl"]; |     var baseUrl = builder.Configuration["ElectoralApi:BaseUrl"]; | ||||||
| @@ -26,13 +40,44 @@ builder.Services.AddHttpClient("ElectoralApiClient", client => | |||||||
|     { |     { | ||||||
|         client.BaseAddress = new Uri(baseUrl); |         client.BaseAddress = new Uri(baseUrl); | ||||||
|     } |     } | ||||||
|  | }) | ||||||
|  | .ConfigurePrimaryHttpMessageHandler(() => | ||||||
|  | { | ||||||
|  |     return new SocketsHttpHandler | ||||||
|  |     { | ||||||
|  |         SslOptions = new SslClientAuthenticationOptions | ||||||
|  |         { | ||||||
|  |             // Forzamos el protocolo TLS 1.3 | ||||||
|  |             EnabledSslProtocols = SslProtocols.Tls13, | ||||||
|  |  | ||||||
|  |             // --- ¡¡¡LA LÍNEA CLAVE CORREGIDA!!! --- | ||||||
|  |             // Forzamos explícitamente los únicos 3 cipher suites que el servidor acepta. | ||||||
|  |             CipherSuitesPolicy = new CipherSuitesPolicy(new[] | ||||||
|  |             { | ||||||
|  |                 TlsCipherSuite.TLS_AES_128_GCM_SHA256, | ||||||
|  |                 TlsCipherSuite.TLS_AES_256_GCM_SHA384, | ||||||
|  |                 TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256 | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
| }); | }); | ||||||
|  |  | ||||||
| builder.Services.AddSingleton<IElectoralApiService, ElectoralApiService>(); | builder.Services.AddSingleton<IElectoralApiService, ElectoralApiService>(); | ||||||
|  | // --- FIN DE LA SECCIÓN MODIFICADA --- | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // 3. Registrar el Worker como un servicio que se ejecuta en segundo plano. |  | ||||||
| builder.Services.AddHostedService<Worker>(); | builder.Services.AddHostedService<Worker>(); | ||||||
|  |  | ||||||
|  |  | ||||||
| var host = builder.Build(); | var host = builder.Build(); | ||||||
|  |  | ||||||
|  | try { | ||||||
|     host.Run(); |     host.Run(); | ||||||
|  | } | ||||||
|  | catch (Exception ex) | ||||||
|  | { | ||||||
|  |     Log.Fatal(ex, "El Host de Elecciones.Worker terminó inesperadamente"); | ||||||
|  | } | ||||||
|  | finally | ||||||
|  | { | ||||||
|  |     Log.CloseAndFlush(); | ||||||
|  | } | ||||||
| @@ -28,33 +28,36 @@ public class Worker : BackgroundService | |||||||
|     { |     { | ||||||
|         _logger.LogInformation("Elecciones Worker iniciado a las: {time}", DateTimeOffset.Now); |         _logger.LogInformation("Elecciones Worker iniciado a las: {time}", DateTimeOffset.Now); | ||||||
|  |  | ||||||
|         // --- 1. SINCRONIZACIÓN INICIAL DE CATÁLOGOS --- |  | ||||||
|         // Se ejecuta una sola vez al inicio para poblar las tablas maestras. |  | ||||||
|         await SincronizarCatalogosAsync(stoppingToken); |         await SincronizarCatalogosAsync(stoppingToken); | ||||||
|  |  | ||||||
|         // --- 2. BUCLE DE SONDEO DE RESULTADOS --- |  | ||||||
|         _logger.LogInformation("-------------------------------------------------"); |         _logger.LogInformation("-------------------------------------------------"); | ||||||
|         _logger.LogInformation("Iniciando sondeo periódico de resultados..."); |         _logger.LogInformation("Iniciando sondeo periódico de resultados..."); | ||||||
|         _logger.LogInformation("-------------------------------------------------"); |         _logger.LogInformation("-------------------------------------------------"); | ||||||
|  |  | ||||||
|         while (!stoppingToken.IsCancellationRequested) |         while (!stoppingToken.IsCancellationRequested) | ||||||
|         { |         { | ||||||
|             await SondearResultadosAsync(stoppingToken); |             // Ejecutamos todos los sondeos en paralelo para mayor eficiencia | ||||||
|  |             await Task.WhenAll( | ||||||
|  |                 SondearResultadosAsync(stoppingToken), | ||||||
|  |                 SondearBancasAsync(stoppingToken), | ||||||
|  |                 SondearTelegramasAsync(stoppingToken), | ||||||
|  |                 SondearResumenProvincialAsync(stoppingToken), | ||||||
|  |                 SondearEstadoRecuentoGeneralAsync(stoppingToken) | ||||||
|  |             ); | ||||||
|  |  | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 // Esperamos 10 segundos antes de la siguiente consulta. |                 // Esperamos 1 minuto antes del siguiente ciclo completo de sondeos | ||||||
|                 await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken); |                 _logger.LogInformation("Ciclo de sondeo completado. Esperando 1 minuto para el siguiente..."); | ||||||
|             } |                 await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); | ||||||
|             catch (TaskCanceledException) |  | ||||||
|             { |  | ||||||
|                 // Es normal que esto ocurra cuando se detiene la aplicación. |  | ||||||
|                 break; |  | ||||||
|             } |             } | ||||||
|  |             catch (TaskCanceledException) { break; } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         _logger.LogInformation("Elecciones Worker se está deteniendo."); |         _logger.LogInformation("Elecciones Worker se está deteniendo."); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     private async Task ObtenerTokenSiEsNecesario(CancellationToken stoppingToken) |     private async Task ObtenerTokenSiEsNecesario(CancellationToken stoppingToken) | ||||||
|     { |     { | ||||||
|         // En un futuro, se podría añadir lógica para renovar el token solo cuando expire. |         // En un futuro, se podría añadir lógica para renovar el token solo cuando expire. | ||||||
| @@ -114,7 +117,6 @@ public class Worker : BackgroundService | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // NUEVO MÉTODO AUXILIAR PARA GUARDAR LOS DATOS |  | ||||||
|     private async Task GuardarResultadosDeAmbitoAsync(EleccionesDbContext dbContext, int ambitoId, Elecciones.Core.DTOs.ResultadosDto resultados, CancellationToken stoppingToken) |     private async Task GuardarResultadosDeAmbitoAsync(EleccionesDbContext dbContext, int ambitoId, Elecciones.Core.DTOs.ResultadosDto resultados, CancellationToken stoppingToken) | ||||||
|     { |     { | ||||||
|         // --- ACTUALIZAR O INSERTAR ESTADO RECUENTO --- |         // --- ACTUALIZAR O INSERTAR ESTADO RECUENTO --- | ||||||
| @@ -168,18 +170,58 @@ public class Worker : BackgroundService | |||||||
|             using var scope = _serviceProvider.CreateScope(); |             using var scope = _serviceProvider.CreateScope(); | ||||||
|             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); |             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); | ||||||
|  |  | ||||||
|             _logger.LogInformation("Limpiando tablas maestras para la nueva ingesta..."); |             // --- 1. SINCRONIZACIÓN DE CATEGORÍAS (NUEVO) --- | ||||||
|             await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ResultadosVotos", stoppingToken); |             var categoriasApi = await _apiService.GetCategoriasAsync(_authToken); | ||||||
|             await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM EstadosRecuentos", stoppingToken); |             if (categoriasApi is { Count: > 0 }) | ||||||
|             await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM AgrupacionesPoliticas", stoppingToken); |             { | ||||||
|             await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM AmbitosGeograficos", stoppingToken); |                 var categoriasEnDb = await dbContext.CategoriasElectorales.ToDictionaryAsync(c => c.Id, c => c, stoppingToken); | ||||||
|  |                 foreach (var categoriaDto in categoriasApi) | ||||||
|  |                 { | ||||||
|  |                     if (categoriasEnDb.TryGetValue(categoriaDto.CategoriaId, out var categoriaExistente)) | ||||||
|  |                     { | ||||||
|  |                         categoriaExistente.Nombre = categoriaDto.Nombre; | ||||||
|  |                         categoriaExistente.Orden = categoriaDto.Orden; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         await dbContext.CategoriasElectorales.AddAsync(new CategoriaElectoral | ||||||
|  |                         { | ||||||
|  |                             Id = categoriaDto.CategoriaId, | ||||||
|  |                             Nombre = categoriaDto.Nombre, | ||||||
|  |                             Orden = categoriaDto.Orden | ||||||
|  |                         }, stoppingToken); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 _logger.LogInformation("Sincronización de Categorías Electorales completada."); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 _logger.LogWarning("No se recibieron datos del catálogo de Categorías."); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             // --- 1. INGESTA DE ÁMBITOS GEOGRÁFICOS --- |             // --- 2. SINCRONIZACIÓN DE ÁMBITOS GEOGRÁFICOS --- | ||||||
|             var catalogos = await _apiService.GetCatalogoCompletoAsync(_authToken); |             var catalogoAmbitosApi = await _apiService.GetCatalogoCompletoAsync(_authToken); | ||||||
|             if (catalogos is { Count: > 0 }) |             if (catalogoAmbitosApi is { Count: > 0 }) | ||||||
|             { |             { | ||||||
|                 foreach (var ambitoDto in catalogos.SelectMany(c => c.Ambitos)) |                 // Cargamos los ámbitos existentes de la BD en un diccionario para búsqueda rápida | ||||||
|  |                 var ambitosEnDb = await dbContext.AmbitosGeograficos | ||||||
|  |                     .ToDictionaryAsync(a => a.MunicipioId ?? a.SeccionId ?? a.DistritoId ?? a.Nombre, a => a, stoppingToken); | ||||||
|  |  | ||||||
|  |                 foreach (var ambitoDto in catalogoAmbitosApi.SelectMany(c => c.Ambitos)) | ||||||
|                 { |                 { | ||||||
|  |                     // Usamos una clave única para identificar el ámbito (ej. ID de municipio) | ||||||
|  |                     var claveUnica = ambitoDto.CodigoAmbitos.MunicipioId ?? ambitoDto.CodigoAmbitos.SeccionId ?? ambitoDto.CodigoAmbitos.DistritoId ?? ambitoDto.Nombre; | ||||||
|  |  | ||||||
|  |                     if (ambitosEnDb.TryGetValue(claveUnica, out var ambitoExistente)) | ||||||
|  |                     { | ||||||
|  |                         // El ámbito ya existe, actualizamos sus datos descriptivos. | ||||||
|  |                         // No actualizamos los IDs, ya que forman parte de la identidad del ámbito. | ||||||
|  |                         ambitoExistente.Nombre = ambitoDto.Nombre; | ||||||
|  |                         ambitoExistente.NivelId = ambitoDto.NivelId; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         // El ámbito es nuevo, lo añadimos (el código de inserción que ya tenemos es correcto) | ||||||
|                         var nuevoAmbito = new AmbitoGeografico |                         var nuevoAmbito = new AmbitoGeografico | ||||||
|                         { |                         { | ||||||
|                             Nombre = ambitoDto.Nombre, |                             Nombre = ambitoDto.Nombre, | ||||||
| @@ -191,19 +233,32 @@ public class Worker : BackgroundService | |||||||
|                         }; |                         }; | ||||||
|                         await dbContext.AmbitosGeograficos.AddAsync(nuevoAmbito, stoppingToken); |                         await dbContext.AmbitosGeograficos.AddAsync(nuevoAmbito, stoppingToken); | ||||||
|                     } |                     } | ||||||
|                 _logger.LogInformation("Datos de Ámbitos Geográficos listos para ser guardados."); |                 } | ||||||
|  |                 _logger.LogInformation("Sincronización de Ámbitos Geográficos completada."); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 _logger.LogWarning("No se recibieron datos del catálogo de Ámbitos."); |                 _logger.LogWarning("No se recibieron datos del catálogo de Ámbitos. Los datos existentes no serán modificados."); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // --- 2. INGESTA DE AGRUPACIONES POLÍTICAS --- |             // --- 3. SINCRONIZACIÓN DE AGRUPACIONES POLÍTICAS --- | ||||||
|             var agrupaciones = await _apiService.GetAgrupacionesAsync(_authToken, "02", 5); |             var agrupacionesApi = await _apiService.GetAgrupacionesAsync(_authToken, "02", 5); | ||||||
|             if (agrupaciones is { Count: > 0 }) |             if (agrupacionesApi is { Count: > 0 }) | ||||||
|             { |             { | ||||||
|                 foreach (var agrupacionDto in agrupaciones) |                 var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas | ||||||
|  |                     .ToDictionaryAsync(a => a.Id, a => a, stoppingToken); | ||||||
|  |  | ||||||
|  |                 foreach (var agrupacionDto in agrupacionesApi) | ||||||
|                 { |                 { | ||||||
|  |                     if (agrupacionesEnDb.TryGetValue(agrupacionDto.IdAgrupacion, out var agrupacionExistente)) | ||||||
|  |                     { | ||||||
|  |                         // La agrupación ya existe, actualizamos el nombre por si cambia | ||||||
|  |                         agrupacionExistente.Nombre = agrupacionDto.NombreAgrupacion; | ||||||
|  |                         agrupacionExistente.IdTelegrama = agrupacionDto.IdAgrupacionTelegrama; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         // La agrupación es nueva, la añadimos | ||||||
|                         var nuevaAgrupacion = new AgrupacionPolitica |                         var nuevaAgrupacion = new AgrupacionPolitica | ||||||
|                         { |                         { | ||||||
|                             Id = agrupacionDto.IdAgrupacion, |                             Id = agrupacionDto.IdAgrupacion, | ||||||
| @@ -212,22 +267,262 @@ public class Worker : BackgroundService | |||||||
|                         }; |                         }; | ||||||
|                         await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); |                         await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); | ||||||
|                     } |                     } | ||||||
|                 _logger.LogInformation("Datos de Agrupaciones Políticas listos para ser guardados."); |                 } | ||||||
|  |                 _logger.LogInformation("Sincronización de Agrupaciones Políticas completada."); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 _logger.LogWarning("No se recibieron datos del catálogo de Agrupaciones."); |                 _logger.LogWarning("No se recibieron datos del catálogo de Agrupaciones. Los datos existentes no serán modificados."); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // --- 3. GUARDADO FINAL EN LA BASE DE DATOS --- |             // --- 4. GUARDADO FINAL --- | ||||||
|             int registrosGuardados = await dbContext.SaveChangesAsync(stoppingToken); |             int cambiosGuardados = await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|             _logger.LogInformation("{count} registros totales han sido guardados en la base de datos.", registrosGuardados); |             _logger.LogInformation("{count} cambios en los catálogos han sido guardados en la base de datos.", cambiosGuardados); | ||||||
|  |  | ||||||
|             _logger.LogInformation("Sincronización de catálogos completada exitosamente."); |             _logger.LogInformation("Sincronización de catálogos maestros finalizada."); | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch (Exception ex) | ||||||
|         { |         { | ||||||
|             _logger.LogError(ex, "Ocurrió un error CRÍTICO durante la sincronización de catálogos. El worker podría no funcionar correctamente."); |             _logger.LogError(ex, "Ocurrió un error CRÍTICO durante la sincronización de catálogos."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task SondearBancasAsync(CancellationToken stoppingToken) | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             await ObtenerTokenSiEsNecesario(stoppingToken); | ||||||
|  |             if (string.IsNullOrEmpty(_authToken) || stoppingToken.IsCancellationRequested) return; | ||||||
|  |  | ||||||
|  |             using var scope = _serviceProvider.CreateScope(); | ||||||
|  |             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); | ||||||
|  |  | ||||||
|  |             // Obtenemos las secciones electorales (donde se reparten bancas de diputados) | ||||||
|  |             var secciones = await dbContext.AmbitosGeograficos | ||||||
|  |                 .AsNoTracking() | ||||||
|  |                 .Where(a => a.NivelId == 4 && a.DistritoId != null && a.SeccionId != null) // Nivel 4 = Sección Electoral | ||||||
|  |                 .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|  |             if (!secciones.Any()) | ||||||
|  |             { | ||||||
|  |                 _logger.LogWarning("No se encontraron ámbitos de tipo 'Sección Electoral' en la BD para sondear bancas."); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             _logger.LogInformation("Iniciando sondeo de Bancas para {count} secciones...", secciones.Count); | ||||||
|  |  | ||||||
|  |             // Esta bandera nos asegura que solo borramos la tabla una vez y solo si hay datos nuevos. | ||||||
|  |             bool hasReceivedNewData = false; | ||||||
|  |  | ||||||
|  |             foreach (var seccion in secciones) | ||||||
|  |             { | ||||||
|  |                 if (stoppingToken.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|  |                 var repartoBancas = await _apiService.GetBancasAsync(_authToken, seccion.DistritoId!, seccion.SeccionId!); | ||||||
|  |  | ||||||
|  |                 // Verificamos que la respuesta no sea nula y que la lista de bancas contenga al menos un elemento. | ||||||
|  |                 if (repartoBancas?.RepartoBancas is { Count: > 0 }) | ||||||
|  |                 { | ||||||
|  |                     // Si esta es la primera vez en este ciclo de sondeo que recibimos datos válidos, | ||||||
|  |                     // borramos todos los datos viejos de la tabla. | ||||||
|  |                     if (!hasReceivedNewData) | ||||||
|  |                     { | ||||||
|  |                         _logger.LogInformation("Se recibieron nuevos datos de bancas. Limpiando tabla de proyecciones..."); | ||||||
|  |                         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); | ||||||
|  |                         hasReceivedNewData = true; // Marcamos que ya hemos limpiado la tabla. | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     // Procedemos a añadir las nuevas proyecciones a la sesión de EF Core. | ||||||
|  |                     foreach (var banca in repartoBancas.RepartoBancas) | ||||||
|  |                     { | ||||||
|  |                         var nuevaProyeccion = new ProyeccionBanca | ||||||
|  |                         { | ||||||
|  |                             AmbitoGeograficoId = seccion.Id, | ||||||
|  |                             AgrupacionPoliticaId = banca.IdAgrupacion, | ||||||
|  |                             NroBancas = banca.NroBancas | ||||||
|  |                         }; | ||||||
|  |                         await dbContext.ProyeccionesBancas.AddAsync(nuevaProyeccion, stoppingToken); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     _logger.LogWarning("No se recibieron datos de bancas para la sección {seccionId}.", seccion.SeccionId); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Si hemos añadido alguna entidad nueva (es decir, hasReceivedNewData es true), | ||||||
|  |             // guardamos todos los cambios en la base de datos. | ||||||
|  |             if (hasReceivedNewData) | ||||||
|  |             { | ||||||
|  |                 await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|  |                 _logger.LogInformation("Sondeo de Bancas completado. La tabla de proyecciones ha sido actualizada."); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 _logger.LogInformation("Sondeo de Bancas completado. No se encontraron datos nuevos, la tabla no fue modificada."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         catch (Exception ex) | ||||||
|  |         { | ||||||
|  |             _logger.LogError(ex, "Ocurrió un error en el sondeo de Bancas."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task SondearTelegramasAsync(CancellationToken stoppingToken) | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             await ObtenerTokenSiEsNecesario(stoppingToken); | ||||||
|  |             if (string.IsNullOrEmpty(_authToken) || stoppingToken.IsCancellationRequested) return; | ||||||
|  |  | ||||||
|  |             // --- CADA SONDEO USA SU PROPIO DBCONTEXT FRESCO --- | ||||||
|  |             using var scope = _serviceProvider.CreateScope(); | ||||||
|  |             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); | ||||||
|  |  | ||||||
|  |             var secciones = await dbContext.AmbitosGeograficos | ||||||
|  |                 .AsNoTracking() | ||||||
|  |                 .Where(a => a.NivelId == 4 && a.DistritoId != null && a.SeccionId != null) | ||||||
|  |                 .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|  |             if (!secciones.Any()) return; | ||||||
|  |  | ||||||
|  |             _logger.LogInformation("Iniciando sondeo de Telegramas nuevos..."); | ||||||
|  |  | ||||||
|  |             foreach (var seccion in secciones) | ||||||
|  |             { | ||||||
|  |                 if (stoppingToken.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|  |                 var listaTelegramasApi = await _apiService.GetTelegramasTotalizadosAsync(_authToken, seccion.DistritoId!, seccion.SeccionId!); | ||||||
|  |                 if (listaTelegramasApi is { Count: > 0 }) | ||||||
|  |                 { | ||||||
|  |                     var idsDeApi = listaTelegramasApi.Select(t => t[0]).Distinct().ToList(); | ||||||
|  |  | ||||||
|  |                     // --- LÓGICA DE DUPLICADOS --- | ||||||
|  |                     // Consultamos a la base de datos por los IDs que la API nos acaba de dar | ||||||
|  |                     var idsYaEnDb = await dbContext.Telegramas | ||||||
|  |                         .Where(t => idsDeApi.Contains(t.Id)) | ||||||
|  |                         .Select(t => t.Id) | ||||||
|  |                         .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|  |                     // Comparamos las dos listas para encontrar los que realmente son nuevos | ||||||
|  |                     var nuevosTelegramasIds = idsDeApi.Except(idsYaEnDb).ToList(); | ||||||
|  |  | ||||||
|  |                     if (!nuevosTelegramasIds.Any()) | ||||||
|  |                     { | ||||||
|  |                         _logger.LogInformation("No hay telegramas nuevos para la sección {seccionId}.", seccion.SeccionId); | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     _logger.LogInformation("Se encontraron {count} telegramas nuevos en la sección {seccionId}. Descargando...", nuevosTelegramasIds.Count, seccion.SeccionId); | ||||||
|  |  | ||||||
|  |                     foreach (var mesaId in nuevosTelegramasIds) | ||||||
|  |                     { | ||||||
|  |                         if (stoppingToken.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|  |                         var telegramaFile = await _apiService.GetTelegramaFileAsync(_authToken, mesaId); | ||||||
|  |                         if (telegramaFile != null) | ||||||
|  |                         { | ||||||
|  |                             var nuevoTelegrama = new Telegrama | ||||||
|  |                             { | ||||||
|  |                                 Id = telegramaFile.NombreArchivo, | ||||||
|  |                                 AmbitoGeograficoId = seccion.Id, // Lo asociamos a la sección por simplicidad | ||||||
|  |                                 ContenidoBase64 = telegramaFile.Imagen, | ||||||
|  |                                 FechaEscaneo = DateTime.Parse(telegramaFile.FechaEscaneo).ToUniversalTime(), | ||||||
|  |                                 FechaTotalizacion = DateTime.Parse(telegramaFile.FechaTotalizacion).ToUniversalTime() | ||||||
|  |                             }; | ||||||
|  |                             // Como estamos en un DbContext fresco, AddAsync no dará conflicto | ||||||
|  |                             await dbContext.Telegramas.AddAsync(nuevoTelegrama, stoppingToken); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     // Guardamos los cambios al final de cada sección procesada | ||||||
|  |                     await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             _logger.LogInformation("Sondeo de Telegramas completado."); | ||||||
|  |         } | ||||||
|  |         catch (Exception ex) | ||||||
|  |         { | ||||||
|  |             _logger.LogError(ex, "Ocurrió un error en el sondeo de Telegramas."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task SondearResumenProvincialAsync(CancellationToken stoppingToken) | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             await ObtenerTokenSiEsNecesario(stoppingToken); | ||||||
|  |             if (string.IsNullOrEmpty(_authToken)) return; | ||||||
|  |  | ||||||
|  |             using var scope = _serviceProvider.CreateScope(); | ||||||
|  |             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); | ||||||
|  |  | ||||||
|  |             var provincia = await dbContext.AmbitosGeograficos.AsNoTracking().FirstOrDefaultAsync(a => a.NivelId == 10, stoppingToken); | ||||||
|  |             if (provincia == null) return; | ||||||
|  |  | ||||||
|  |             var resumen = await _apiService.GetResumenAsync(_authToken, provincia.DistritoId!); | ||||||
|  |             if (resumen?.ValoresTotalizadosPositivos is { Count: > 0 }) | ||||||
|  |             { | ||||||
|  |                 // Estrategia: Reemplazo completo | ||||||
|  |                 await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ResumenesVotos", stoppingToken); | ||||||
|  |                 foreach (var voto in resumen.ValoresTotalizadosPositivos) | ||||||
|  |                 { | ||||||
|  |                     await dbContext.ResumenesVotos.AddAsync(new ResumenVoto | ||||||
|  |                     { | ||||||
|  |                         AmbitoGeograficoId = provincia.Id, | ||||||
|  |                         AgrupacionPoliticaId = voto.IdAgrupacion, | ||||||
|  |                         Votos = voto.Votos, | ||||||
|  |                         VotosPorcentaje = voto.VotosPorcentaje | ||||||
|  |                     }, stoppingToken); | ||||||
|  |                 } | ||||||
|  |                 await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|  |                 _logger.LogInformation("Sondeo de Resumen Provincial completado."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         catch (Exception ex) | ||||||
|  |         { | ||||||
|  |             _logger.LogError(ex, "Ocurrió un error en el sondeo de Resumen Provincial."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task SondearEstadoRecuentoGeneralAsync(CancellationToken stoppingToken) | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             await ObtenerTokenSiEsNecesario(stoppingToken); | ||||||
|  |             if (string.IsNullOrEmpty(_authToken)) return; | ||||||
|  |  | ||||||
|  |             using var scope = _serviceProvider.CreateScope(); | ||||||
|  |             var dbContext = scope.ServiceProvider.GetRequiredService<EleccionesDbContext>(); | ||||||
|  |  | ||||||
|  |             var provincia = await dbContext.AmbitosGeograficos.AsNoTracking().FirstOrDefaultAsync(a => a.NivelId == 10, stoppingToken); | ||||||
|  |             if (provincia == null) return; | ||||||
|  |  | ||||||
|  |             var estadoDto = await _apiService.GetEstadoRecuentoGeneralAsync(_authToken, provincia.DistritoId!); | ||||||
|  |             if (estadoDto != null) | ||||||
|  |             { | ||||||
|  |                 // Estrategia: Upsert | ||||||
|  |                 var registroDb = await dbContext.EstadosRecuentosGenerales.FindAsync(provincia.Id); | ||||||
|  |                 if (registroDb == null) | ||||||
|  |                 { | ||||||
|  |                     registroDb = new EstadoRecuentoGeneral { AmbitoGeograficoId = provincia.Id }; | ||||||
|  |                     dbContext.EstadosRecuentosGenerales.Add(registroDb); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 registroDb.MesasEsperadas = estadoDto.MesasEsperadas; | ||||||
|  |                 registroDb.MesasTotalizadas = estadoDto.MesasTotalizadas; | ||||||
|  |                 registroDb.MesasTotalizadasPorcentaje = estadoDto.MesasTotalizadasPorcentaje; | ||||||
|  |                 registroDb.CantidadElectores = estadoDto.CantidadElectores; | ||||||
|  |                 registroDb.CantidadVotantes = estadoDto.CantidadVotantes; | ||||||
|  |                 registroDb.ParticipacionPorcentaje = estadoDto.ParticipacionPorcentaje; | ||||||
|  |  | ||||||
|  |                 await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|  |                 _logger.LogInformation("Sondeo de Estado Recuento General completado."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         catch (Exception ex) | ||||||
|  |         { | ||||||
|  |             _logger.LogError(ex, "Ocurrió un error en el sondeo de Estado Recuento General."); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -12,7 +12,11 @@ | |||||||
|           "Elecciones.Infrastructure": "1.0.0", |           "Elecciones.Infrastructure": "1.0.0", | ||||||
|           "Microsoft.EntityFrameworkCore.SqlServer": "9.0.8", |           "Microsoft.EntityFrameworkCore.SqlServer": "9.0.8", | ||||||
|           "Microsoft.Extensions.Hosting": "9.0.5", |           "Microsoft.Extensions.Hosting": "9.0.5", | ||||||
|           "Microsoft.Extensions.Http": "9.0.8" |           "Microsoft.Extensions.Http": "9.0.8", | ||||||
|  |           "Serilog.Extensions.Hosting": "9.0.0", | ||||||
|  |           "Serilog.Settings.Configuration": "9.0.0", | ||||||
|  |           "Serilog.Sinks.Console": "6.0.0", | ||||||
|  |           "Serilog.Sinks.File": "7.0.0" | ||||||
|         }, |         }, | ||||||
|         "runtime": { |         "runtime": { | ||||||
|           "Elecciones.Worker.dll": {} |           "Elecciones.Worker.dll": {} | ||||||
| @@ -323,6 +327,14 @@ | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |       "Microsoft.Extensions.DependencyModel/9.0.0": { | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Microsoft.Extensions.DependencyModel.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.24.52809" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|       "Microsoft.Extensions.Diagnostics/9.0.8": { |       "Microsoft.Extensions.Diagnostics/9.0.8": { | ||||||
|         "dependencies": { |         "dependencies": { | ||||||
|           "Microsoft.Extensions.Configuration": "9.0.8", |           "Microsoft.Extensions.Configuration": "9.0.8", | ||||||
| @@ -698,6 +710,76 @@ | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |       "Serilog/4.2.0": { | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.dll": { | ||||||
|  |             "assemblyVersion": "4.2.0.0", | ||||||
|  |             "fileVersion": "4.2.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Extensions.Hosting/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.Hosting.Abstractions": "9.0.5", | ||||||
|  |           "Microsoft.Extensions.Logging.Abstractions": "9.0.8", | ||||||
|  |           "Serilog": "4.2.0", | ||||||
|  |           "Serilog.Extensions.Logging": "9.0.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Extensions.Hosting.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Extensions.Logging/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Logging": "9.0.8", | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Extensions.Logging.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Settings.Configuration/9.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Microsoft.Extensions.Configuration.Binder": "9.0.8", | ||||||
|  |           "Microsoft.Extensions.DependencyModel": "9.0.0", | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Settings.Configuration.dll": { | ||||||
|  |             "assemblyVersion": "9.0.0.0", | ||||||
|  |             "fileVersion": "9.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Sinks.Console/6.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net8.0/Serilog.Sinks.Console.dll": { | ||||||
|  |             "assemblyVersion": "6.0.0.0", | ||||||
|  |             "fileVersion": "6.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "Serilog.Sinks.File/7.0.0": { | ||||||
|  |         "dependencies": { | ||||||
|  |           "Serilog": "4.2.0" | ||||||
|  |         }, | ||||||
|  |         "runtime": { | ||||||
|  |           "lib/net9.0/Serilog.Sinks.File.dll": { | ||||||
|  |             "assemblyVersion": "7.0.0.0", | ||||||
|  |             "fileVersion": "7.0.0.0" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|       "System.ClientModel/1.0.0": { |       "System.ClientModel/1.0.0": { | ||||||
|         "dependencies": { |         "dependencies": { | ||||||
|           "System.Memory.Data": "1.0.2", |           "System.Memory.Data": "1.0.2", | ||||||
| @@ -1115,6 +1197,13 @@ | |||||||
|       "path": "microsoft.extensions.dependencyinjection.abstractions/9.0.8", |       "path": "microsoft.extensions.dependencyinjection.abstractions/9.0.8", | ||||||
|       "hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.8.nupkg.sha512" |       "hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.8.nupkg.sha512" | ||||||
|     }, |     }, | ||||||
|  |     "Microsoft.Extensions.DependencyModel/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-saxr2XzwgDU77LaQfYFXmddEDRUKHF4DaGMZkNB3qjdVSZlax3//dGJagJkKrGMIPNZs2jVFXITyCCR6UHJNdA==", | ||||||
|  |       "path": "microsoft.extensions.dependencymodel/9.0.0", | ||||||
|  |       "hashPath": "microsoft.extensions.dependencymodel.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|     "Microsoft.Extensions.Diagnostics/9.0.8": { |     "Microsoft.Extensions.Diagnostics/9.0.8": { | ||||||
|       "type": "package", |       "type": "package", | ||||||
|       "serviceable": true, |       "serviceable": true, | ||||||
| @@ -1325,6 +1414,48 @@ | |||||||
|       "path": "microsoft.win32.systemevents/6.0.0", |       "path": "microsoft.win32.systemevents/6.0.0", | ||||||
|       "hashPath": "microsoft.win32.systemevents.6.0.0.nupkg.sha512" |       "hashPath": "microsoft.win32.systemevents.6.0.0.nupkg.sha512" | ||||||
|     }, |     }, | ||||||
|  |     "Serilog/4.2.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-gmoWVOvKgbME8TYR+gwMf7osROiWAURterc6Rt2dQyX7wtjZYpqFiA/pY6ztjGQKKV62GGCyOcmtP1UKMHgSmA==", | ||||||
|  |       "path": "serilog/4.2.0", | ||||||
|  |       "hashPath": "serilog.4.2.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Extensions.Hosting/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-u2TRxuxbjvTAldQn7uaAwePkWxTHIqlgjelekBtilAGL5sYyF3+65NWctN4UrwwGLsDC7c3Vz3HnOlu+PcoxXg==", | ||||||
|  |       "path": "serilog.extensions.hosting/9.0.0", | ||||||
|  |       "hashPath": "serilog.extensions.hosting.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Extensions.Logging/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==", | ||||||
|  |       "path": "serilog.extensions.logging/9.0.0", | ||||||
|  |       "hashPath": "serilog.extensions.logging.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Settings.Configuration/9.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-4/Et4Cqwa+F88l5SeFeNZ4c4Z6dEAIKbu3MaQb2Zz9F/g27T5a3wvfMcmCOaAiACjfUb4A6wrlTVfyYUZk3RRQ==", | ||||||
|  |       "path": "serilog.settings.configuration/9.0.0", | ||||||
|  |       "hashPath": "serilog.settings.configuration.9.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Sinks.Console/6.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-fQGWqVMClCP2yEyTXPIinSr5c+CBGUvBybPxjAGcf7ctDhadFhrQw03Mv8rJ07/wR5PDfFjewf2LimvXCDzpbA==", | ||||||
|  |       "path": "serilog.sinks.console/6.0.0", | ||||||
|  |       "hashPath": "serilog.sinks.console.6.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|  |     "Serilog.Sinks.File/7.0.0": { | ||||||
|  |       "type": "package", | ||||||
|  |       "serviceable": true, | ||||||
|  |       "sha512": "sha512-fKL7mXv7qaiNBUC71ssvn/dU0k9t0o45+qm2XgKAlSt19xF+ijjxyA3R6HmCgfKEKwfcfkwWjayuQtRueZFkYw==", | ||||||
|  |       "path": "serilog.sinks.file/7.0.0", | ||||||
|  |       "hashPath": "serilog.sinks.file.7.0.0.nupkg.sha512" | ||||||
|  |     }, | ||||||
|     "System.ClientModel/1.0.0": { |     "System.ClientModel/1.0.0": { | ||||||
|       "type": "package", |       "type": "package", | ||||||
|       "serviceable": true, |       "serviceable": true, | ||||||
|   | |||||||
| @@ -4,10 +4,5 @@ | |||||||
|       "Default": "Information", |       "Default": "Information", | ||||||
|       "Microsoft.Hosting.Lifetime": "Information" |       "Microsoft.Hosting.Lifetime": "Information" | ||||||
|     } |     } | ||||||
|   }, |  | ||||||
|   "ElectoralApi": { |  | ||||||
|     "BaseUrl": "https://api.eleccionesbonaerenses.gba.gob.ar", |  | ||||||
|     "Username": "30500094156@elecciones2025.onmicrosoft.com", |  | ||||||
|     "Password": "PTP847elec" |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | { | ||||||
|  |   "runtimeOptions": { | ||||||
|  |     "tfm": "net9.0", | ||||||
|  |     "framework": { | ||||||
|  |       "name": "Microsoft.NETCore.App", | ||||||
|  |       "version": "9.0.0" | ||||||
|  |     }, | ||||||
|  |     "configProperties": { | ||||||
|  |       "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, | ||||||
|  |       "System.Reflection.NullabilityInfoContext.IsSupported": true, | ||||||
|  |       "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | { | ||||||
|  |   "Logging": { | ||||||
|  |     "LogLevel": { | ||||||
|  |       "Default": "Information", | ||||||
|  |       "Microsoft.Hosting.Lifetime": "Information" | ||||||
|  |     } | ||||||
|  |     }, | ||||||
|  |   "ElectoralApi": { | ||||||
|  |     "BaseUrl": "https://api.eleccionesbonaerenses.gba.gob.ar", | ||||||
|  |     "Username": "30500094156@elecciones2025.onmicrosoft.com", | ||||||
|  |     "Password": "PTP847elec" | ||||||
|  |   }, | ||||||
|  |   "ConnectionStrings": { | ||||||
|  |     "DefaultConnection": "Server=TECNICA3;Database=Elecciones2025;User Id=apielecciones2025;Password=PTP847Elecciones2025;Encrypt=False;MultipleActiveResultSets=True;TrustServerCertificate=True;" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "Logging": { | ||||||
|  |     "LogLevel": { | ||||||
|  |       "Default": "Information", | ||||||
|  |       "Microsoft.Hosting.Lifetime": "Information" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -14,7 +14,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Worker")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Worker")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b90baadeedb870b5b1c9eeeb7022a0d211b61bec")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Worker")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Worker")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Worker")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Worker")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -96,3 +96,11 @@ E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Debug\net9.0\Eleccio | |||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Debug\net9.0\Elecciones.Worker.genruntimeconfig.cache | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Debug\net9.0\Elecciones.Worker.genruntimeconfig.cache | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Debug\net9.0\ref\Elecciones.Worker.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Debug\net9.0\ref\Elecciones.Worker.dll | ||||||
| E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Microsoft.Extensions.Http.dll | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Microsoft.Extensions.Http.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\buenos-aires-municipios.geojson | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Microsoft.Extensions.DependencyModel.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.Extensions.Hosting.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.Extensions.Logging.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.Settings.Configuration.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.Sinks.Console.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Debug\net9.0\Serilog.Sinks.File.dll | ||||||
|   | |||||||
| @@ -289,6 +289,22 @@ | |||||||
|             "Microsoft.Extensions.Http": { |             "Microsoft.Extensions.Http": { | ||||||
|               "target": "Package", |               "target": "Package", | ||||||
|               "version": "[9.0.8, )" |               "version": "[9.0.8, )" | ||||||
|  |             }, | ||||||
|  |             "Serilog.Extensions.Hosting": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[9.0.0, )" | ||||||
|  |             }, | ||||||
|  |             "Serilog.Settings.Configuration": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[9.0.0, )" | ||||||
|  |             }, | ||||||
|  |             "Serilog.Sinks.Console": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[6.0.0, )" | ||||||
|  |             }, | ||||||
|  |             "Serilog.Sinks.File": { | ||||||
|  |               "target": "Package", | ||||||
|  |               "version": "[7.0.0, )" | ||||||
|             } |             } | ||||||
|           }, |           }, | ||||||
|           "imports": [ |           "imports": [ | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
| <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|   <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |   <ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> | ||||||
|     <Import Project="$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets')" /> |     <Import Project="$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\9.0.8\buildTransitive\net8.0\System.Text.Json.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" /> |  | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\9.0.8\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" /> | ||||||
|  |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.8\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> | ||||||
|     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\9.0.5\buildTransitive\net8.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\9.0.5\buildTransitive\net8.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" /> |     <Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\9.0.5\buildTransitive\net8.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\9.0.5\buildTransitive\net8.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" /> | ||||||
|   </ImportGroup> |   </ImportGroup> | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | // <autogenerated /> | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // <auto-generated> | ||||||
|  | //     This code was generated by a tool. | ||||||
|  | // | ||||||
|  | //     Changes to this file may cause incorrect behavior and will be lost if | ||||||
|  | //     the code is regenerated. | ||||||
|  | // </auto-generated> | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | [assembly: Microsoft.Extensions.Configuration.UserSecrets.UserSecretsIdAttribute("dotnet-Elecciones.Worker-b1c6e5c0-7ebf-4eaf-af95-9386d6883c03")] | ||||||
|  | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Worker")] | ||||||
|  | [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] | ||||||
|  | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
|  | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+39b1e9707275ed59ac4a7d32e26b951186a346bb")] | ||||||
|  | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Worker")] | ||||||
|  | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Worker")] | ||||||
|  | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|  |  | ||||||
|  | // Generado por la clase WriteCodeFragment de MSBuild. | ||||||
|  |  | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | is_global = true | ||||||
|  | build_property.TargetFramework = net9.0 | ||||||
|  | build_property.TargetPlatformMinVersion =  | ||||||
|  | build_property.UsingMicrosoftNETSdkWeb =  | ||||||
|  | build_property.ProjectTypeGuids =  | ||||||
|  | build_property.InvariantGlobalization =  | ||||||
|  | build_property.PlatformNeutralAssembly =  | ||||||
|  | build_property.EnforceExtendedAnalyzerRules =  | ||||||
|  | build_property._SupportedPlatformList = Linux,macOS,Windows | ||||||
|  | build_property.RootNamespace = Elecciones.Worker | ||||||
|  | build_property.ProjectDir = E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\ | ||||||
|  | build_property.EnableComHosting =  | ||||||
|  | build_property.EnableGeneratedComInterfaceComImportInterop =  | ||||||
|  | build_property.EffectiveAnalysisLevelStyle = 9.0 | ||||||
|  | build_property.EnableCodeStyleSeverity =  | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | // <auto-generated/> | ||||||
|  | global using global::Microsoft.Extensions.Configuration; | ||||||
|  | global using global::Microsoft.Extensions.DependencyInjection; | ||||||
|  | global using global::Microsoft.Extensions.Hosting; | ||||||
|  | global using global::Microsoft.Extensions.Logging; | ||||||
|  | global using global::System; | ||||||
|  | global using global::System.Collections.Generic; | ||||||
|  | global using global::System.IO; | ||||||
|  | global using global::System.Linq; | ||||||
|  | global using global::System.Net.Http; | ||||||
|  | global using global::System.Threading; | ||||||
|  | global using global::System.Threading.Tasks; | ||||||
| @@ -0,0 +1,106 @@ | |||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\buenos-aires-municipios.geojson | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\appsettings.Development.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\appsettings.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Worker.exe | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Worker.deps.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Worker.runtimeconfig.json | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Worker.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Worker.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Azure.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Azure.Identity.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Bcl.AsyncInterfaces.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Data.SqlClient.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.EntityFrameworkCore.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.EntityFrameworkCore.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.EntityFrameworkCore.Relational.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.EntityFrameworkCore.SqlServer.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Caching.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Caching.Memory.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.Binder.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.CommandLine.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.EnvironmentVariables.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.FileExtensions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.Json.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Configuration.UserSecrets.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.DependencyInjection.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.DependencyModel.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Diagnostics.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Diagnostics.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.FileProviders.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.FileProviders.Physical.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.FileSystemGlobbing.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Hosting.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Hosting.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Http.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.Configuration.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.Console.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.Debug.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.EventLog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Logging.EventSource.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Options.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Extensions.Primitives.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Identity.Client.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Identity.Client.Extensions.Msal.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.Abstractions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.JsonWebTokens.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.Logging.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.Protocols.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.IdentityModel.Tokens.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.SqlServer.Server.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Microsoft.Win32.SystemEvents.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.Extensions.Hosting.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.Extensions.Logging.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.Settings.Configuration.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.Sinks.Console.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Serilog.Sinks.File.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.ClientModel.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Configuration.ConfigurationManager.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Diagnostics.EventLog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Drawing.Common.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Formats.Asn1.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.IdentityModel.Tokens.Jwt.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Memory.Data.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Runtime.Caching.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Security.Cryptography.ProtectedData.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Security.Permissions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Text.Json.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\System.Windows.Extensions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\unix\lib\net6.0\Microsoft.Data.SqlClient.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\Microsoft.Data.SqlClient.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win-arm\native\Microsoft.Data.SqlClient.SNI.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win-arm64\native\Microsoft.Data.SqlClient.SNI.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win-x64\native\Microsoft.Data.SqlClient.SNI.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win-x86\native\Microsoft.Data.SqlClient.SNI.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\Microsoft.Win32.SystemEvents.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net9.0\System.Diagnostics.EventLog.Messages.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net9.0\System.Diagnostics.EventLog.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\unix\lib\net6.0\System.Drawing.Common.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\System.Drawing.Common.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\System.Runtime.Caching.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\System.Security.Cryptography.ProtectedData.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\runtimes\win\lib\net6.0\System.Windows.Extensions.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Core.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Database.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Infrastructure.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Infrastructure.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Database.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\bin\Release\net9.0\Elecciones.Core.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.csproj.AssemblyReference.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.GeneratedMSBuildEditorConfig.editorconfig | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.AssemblyInfoInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.AssemblyInfo.cs | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.csproj.CoreCompileInputs.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Eleccion.0707F6F5.Up2Date | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\refint\Elecciones.Worker.dll | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.pdb | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\Elecciones.Worker.genruntimeconfig.cache | ||||||
|  | E:\Elecciones-2025\Elecciones-Web\src\Elecciones.Worker\obj\Release\net9.0\ref\Elecciones.Worker.dll | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <Target Name="GetEFProjectMetadata"> | ||||||
|  |     <MSBuild Condition=" '$(TargetFramework)' == '' " | ||||||
|  |              Projects="$(MSBuildProjectFile)" | ||||||
|  |              Targets="GetEFProjectMetadata" | ||||||
|  |              Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" /> | ||||||
|  |     <ItemGroup Condition=" '$(TargetFramework)' != '' "> | ||||||
|  |       <EFProjectMetadata Include="AssemblyName: $(AssemblyName)" /> | ||||||
|  |       <EFProjectMetadata Include="Language: $(Language)" /> | ||||||
|  |       <EFProjectMetadata Include="OutputPath: $(OutputPath)" /> | ||||||
|  |       <EFProjectMetadata Include="Platform: $(Platform)" /> | ||||||
|  |       <EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" /> | ||||||
|  |       <EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" /> | ||||||
|  |       <EFProjectMetadata Include="ProjectDir: $(ProjectDir)" /> | ||||||
|  |       <EFProjectMetadata Include="RootNamespace: $(RootNamespace)" /> | ||||||
|  |       <EFProjectMetadata Include="RuntimeFrameworkVersion: $(RuntimeFrameworkVersion)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFileName: $(TargetFileName)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" /> | ||||||
|  |       <EFProjectMetadata Include="Nullable: $(Nullable)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFramework: $(TargetFramework)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetPlatformIdentifier: $(TargetPlatformIdentifier)" /> | ||||||
|  |     </ItemGroup> | ||||||
|  |     <WriteLinesToFile Condition=" '$(TargetFramework)' != '' " | ||||||
|  |                       File="$(EFProjectMetadataFile)" | ||||||
|  |                       Lines="@(EFProjectMetadata)" /> | ||||||
|  |   </Target> | ||||||
|  | </Project> | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <Target Name="GetEFProjectMetadata"> | ||||||
|  |     <MSBuild Condition=" '$(TargetFramework)' == '' " | ||||||
|  |              Projects="$(MSBuildProjectFile)" | ||||||
|  |              Targets="GetEFProjectMetadata" | ||||||
|  |              Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" /> | ||||||
|  |     <ItemGroup Condition=" '$(TargetFramework)' != '' "> | ||||||
|  |       <EFProjectMetadata Include="AssemblyName: $(AssemblyName)" /> | ||||||
|  |       <EFProjectMetadata Include="Language: $(Language)" /> | ||||||
|  |       <EFProjectMetadata Include="OutputPath: $(OutputPath)" /> | ||||||
|  |       <EFProjectMetadata Include="Platform: $(Platform)" /> | ||||||
|  |       <EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" /> | ||||||
|  |       <EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" /> | ||||||
|  |       <EFProjectMetadata Include="ProjectDir: $(ProjectDir)" /> | ||||||
|  |       <EFProjectMetadata Include="RootNamespace: $(RootNamespace)" /> | ||||||
|  |       <EFProjectMetadata Include="RuntimeFrameworkVersion: $(RuntimeFrameworkVersion)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFileName: $(TargetFileName)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" /> | ||||||
|  |       <EFProjectMetadata Include="Nullable: $(Nullable)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetFramework: $(TargetFramework)" /> | ||||||
|  |       <EFProjectMetadata Include="TargetPlatformIdentifier: $(TargetPlatformIdentifier)" /> | ||||||
|  |     </ItemGroup> | ||||||
|  |     <WriteLinesToFile Condition=" '$(TargetFramework)' != '' " | ||||||
|  |                       File="$(EFProjectMetadataFile)" | ||||||
|  |                       Lines="@(EFProjectMetadata)" /> | ||||||
|  |   </Target> | ||||||
|  | </Project> | ||||||
							
								
								
									
										78
									
								
								reconcile_ids.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								reconcile_ids.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | // reconcile_ids.js | ||||||
|  | const fs = require('fs'); | ||||||
|  | const path = require('path'); | ||||||
|  | const http = require('http'); | ||||||
|  |  | ||||||
|  | // --- CONFIGURACIÓN --- | ||||||
|  | const API_URL = 'http://localhost:5217/api/catalogos/municipios'; // ¡Asegúrate que tu API esté corriendo en este puerto! | ||||||
|  | const GEOJSON_PATH = path.join(__dirname, 'Elecciones-Web', 'frontend', 'public', 'buenos-aires-municipios.geojson'); | ||||||
|  | const OUTPUT_PATH = path.join(__dirname, 'Elecciones-Web', 'frontend', 'public', 'municipioIdMap.json'); | ||||||
|  |  | ||||||
|  | const normalizeString = (str) => { | ||||||
|  |     if (!str) return ''; | ||||||
|  |     return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | async function reconcile() { | ||||||
|  |     console.log('Iniciando el script de reconciliación de IDs...'); | ||||||
|  |  | ||||||
|  |     try { | ||||||
|  |         const apiData = await new Promise((resolve, reject) => { | ||||||
|  |             http.get(API_URL, res => { | ||||||
|  |                 const { statusCode } = res; | ||||||
|  |                 if (statusCode !== 200) { | ||||||
|  |                     reject(new Error(`La petición a la API falló con el código de estado: ${statusCode}`)); | ||||||
|  |                     res.resume(); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |                 let data = ''; | ||||||
|  |                 res.on('data', chunk => data += chunk); | ||||||
|  |                 res.on('end', () => resolve(JSON.parse(data))); | ||||||
|  |             }).on('error', reject); | ||||||
|  |         }); | ||||||
|  |         console.log(`Se obtuvieron ${apiData.length} municipios desde la API.`); | ||||||
|  |  | ||||||
|  |         const apiNameMap = new Map(apiData.map(m => [normalizeString(m.nombre), m.id])); | ||||||
|  |  | ||||||
|  |         const geoJsonRaw = fs.readFileSync(GEOJSON_PATH, 'utf8'); | ||||||
|  |         const geoJsonData = JSON.parse(geoJsonRaw); | ||||||
|  |         console.log(`Se leyeron ${geoJsonData.features.length} features desde el GeoJSON.`); | ||||||
|  |  | ||||||
|  |         const finalIdMap = {}; | ||||||
|  |         let matches = 0; | ||||||
|  |         const notFound = []; | ||||||
|  |  | ||||||
|  |         // --- CAMBIO CLAVE: YA NO NECESITAMOS ALIAS MANUALES --- | ||||||
|  |  | ||||||
|  |         for (const feature of geoJsonData.features) { | ||||||
|  |             const geoJsonId = feature.properties.cca; | ||||||
|  |             const nombreGeoJson = normalizeString(feature.properties.nam); | ||||||
|  |  | ||||||
|  |             if (apiNameMap.has(nombreGeoJson)) { | ||||||
|  |                 const apiId = apiNameMap.get(nombreGeoJson); | ||||||
|  |                 finalIdMap[geoJsonId] = apiId; | ||||||
|  |                 matches++; | ||||||
|  |             } else { | ||||||
|  |                 notFound.push(feature.properties.nam); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         console.log(`\n--- RESULTADOS ---`); | ||||||
|  |         console.log(`Coincidencias encontradas: ${matches} de ${geoJsonData.features.length}`); | ||||||
|  |         if (notFound.length > 0) { | ||||||
|  |             console.warn(`\nNo se encontró coincidencia para los siguientes ${notFound.length} municipios del GeoJSON:`); | ||||||
|  |             console.warn(notFound.join(', ')); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fs.writeFileSync(OUTPUT_PATH, JSON.stringify(finalIdMap, null, 2)); | ||||||
|  |         console.log(`\n¡Éxito! El mapa de IDs se ha guardado en: ${OUTPUT_PATH}`); | ||||||
|  |  | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error('\nOcurrió un error:', error.message); | ||||||
|  |         if(error.code === 'ECONNREFUSED') { | ||||||
|  |             console.error('Asegúrate de que tu servicio de API esté corriendo en la URL especificada.'); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | reconcile(); | ||||||
		Reference in New Issue
	
	Block a user