diff --git a/.opencode/plans/tsi-barcode-scanning.md b/.opencode/plans/tsi-barcode-scanning.md
new file mode 100644
index 0000000..be88988
--- /dev/null
+++ b/.opencode/plans/tsi-barcode-scanning.md
@@ -0,0 +1,209 @@
+# FarmaFinder — TSI Barcode Scanning + Capacitor 8 Upgrade
+
+## Overview
+
+Two sequential phases:
+1. **Phase A** — Upgrade Capacitor 6 → 8 (prerequisite for latest barcode scanner plugin)
+2. **Phase B** — Implement real TSI barcode scanning with manual CIP entry fallback
+
+---
+
+## Phase A: Upgrade Capacitor 6 → 8
+
+### A1. Upgrade Capacitor packages (root)
+
+```bash
+npm install @capacitor/cli@latest @capacitor/core@latest \
+ @capacitor/android@latest @capacitor/ios@latest \
+ @capacitor/app@latest @capacitor/splash-screen@latest \
+ @capacitor/status-bar@latest
+```
+
+This bumps all `@capacitor/*` from `^6.x` to `^8.x` in `package.json`.
+
+### A2. Update `android/variables.gradle`
+
+Replace all 13 version variables to meet Capacitor 8 minimums:
+
+| Variable | Current | New |
+|---|---|---|
+| `minSdkVersion` | 22 | **24** |
+| `compileSdkVersion` | 34 | **36** |
+| `targetSdkVersion` | 34 | **36** |
+| `androidxActivityVersion` | 1.8.0 | **1.11.0** |
+| `androidxAppCompatVersion` | 1.6.1 | **1.7.1** |
+| `androidxCoordinatorLayoutVersion` | 1.2.0 | **1.3.0** |
+| `androidxCoreVersion` | 1.12.0 | **1.17.0** |
+| `androidxFragmentVersion` | 1.6.2 | **1.8.9** |
+| `coreSplashScreenVersion` | 1.0.1 | **1.2.0** |
+| `androidxWebkitVersion` | 1.9.0 | **1.14.0** |
+| `junitVersion` | 4.13.2 | 4.13.2 (same) |
+| `androidxJunitVersion` | 1.1.5 | **1.3.0** |
+| `androidxEspressoCoreVersion` | 3.5.1 | **3.7.0** |
+| `cordovaAndroidVersion` | 10.1.1 | **14.0.1** |
+
+### A3. Update `ios/App/Podfile`
+
+- Line 3: Change `platform :ios, '13.0'` → `platform :ios, '15.0'`
+
+### A4. Update `android/app/src/main/AndroidManifest.xml`
+
+- Add `density` to `android:configChanges` on line 13:
+ ```
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|density"
+ ```
+
+### A5. Update `android/build.gradle` (Gradle plugin)
+
+- Update Android Gradle Plugin from `8.2.1` → `8.13.0`
+- Update Google Services plugin from `4.4.0` → `4.4.4`
+- Update Gradle wrapper to `8.14.3` in `android/gradle/wrapper/gradle-wrapper.properties`
+
+### A6. Run Capacitor sync
+
+```bash
+npx cap sync
+```
+
+### A7. Verify build
+
+- Open `android/` in Android Studio — confirm Gradle sync succeeds
+- Open `ios/App` in Xcode — confirm pod install succeeds and build compiles
+
+---
+
+## Phase B: Real TSI Barcode Scanning
+
+### B1. Install barcode scanning plugin
+
+From `frontend/`:
+```bash
+npm install @capacitor-mlkit/barcode-scanning@^8.1.0
+npm install barcode-detector # web polyfill for PWA browser fallback
+```
+
+From root:
+```bash
+npx cap sync
+```
+
+**Plugin:** `@capacitor-mlkit/barcode-scanning` v8.1.0 — Google ML Kit engine, 91K+ weekly npm downloads, supports Code 128 (TSI physical card barcode) and QR Code (virtual TSI card).
+
+### B2. Native manifest verification (no changes expected)
+
+| Platform | File | Required | Status |
+|---|---|---|---|
+| Android | `AndroidManifest.xml:44` | `CAMERA` permission | Already present |
+| iOS | `Info.plist:52-53` | `NSCameraUsageDescription` | Already present |
+
+### B3. Rewrite `frontend/src/views/ScannerView.jsx`
+
+**Remove:**
+- `MOCK_TSI_CARDS` array and all mock card state/UI
+- `navigator.mediaDevices.getUserMedia()` camera logic (lines 40-73)
+- Auto-scan `setTimeout` simulation (lines 98-105)
+- Simulated scan fallback panel (lines 170-198)
+- `selectedMockCard` state
+
+**Add:**
+- Import `BarcodeScanner`, `BarcodeFormat`, `LensFacing` from `@capacitor-mlkit/barcode-scanning`
+- Import `Capacitor` from `@capacitor/core` (platform detection)
+- Import `barcode-detector/polyfill` at top (web fallback)
+
+**New scan flow:**
+```
+1. Component mounts → show "Start Scanning" button + manual CIP input
+2. User taps "Start Scanning":
+ a. Check BarcodeScanner.isSupported() → error if not
+ b. Check/request camera permission via BarcodeScanner.checkPermissions() / requestPermissions()
+ c. Call BarcodeScanner.scan({ formats: [BarcodeFormat.Code128, BarcodeFormat.QrCode], autoZoom: true })
+ d. Extract barcodes[0].rawValue (NOTE: can be undefined per v8 breaking change — handle gracefully)
+ e. Validate CIP format: /^[A-Z0-9]{16}$/i
+ f. If valid → fetchPrescriptions(cip) → show prescriptions
+ g. If invalid → show error "Invalid card barcode. Try manual entry."
+3. Manual CIP input:
+ - Text input field with placeholder "Enter CIP code manually"
+ - "Submit" button → validates format → fetchPrescriptions(cip)
+4. PWA/browser fallback:
+ - Detect: !Capacitor.isNativePlatform()
+ - Show message: "Barcode scanning requires the mobile app. Enter your CIP code manually below."
+ - Show only the manual CIP input (no scan button)
+```
+
+**Phases (simplified):**
+- `idle` — initial state, scan button + manual input visible
+- `scanning` — ML Kit native UI active (camera takes over)
+- `prescriptions` — results display (keep existing prescription card UI)
+- `error` — permission denied / unsupported / invalid barcode
+
+**Keep unchanged:**
+- `playBeep()` function
+- `fetchPrescriptions(cip)` function
+- `handlePickPrescription(rx)` function
+- `handleBack()` function
+- Prescription display UI (lines 201-249)
+- `onSelectMedicine` callback prop
+
+### B4. Rewrite `frontend/src/views/ScannerView.css`
+
+**Remove:**
+- `.scanner-viewport-wrap`, `.scanner-camera-container`, `.scanner-video`, `.scanner-frame`, `.scanner-laser`, `.scanner-hint` (old camera overlay)
+- `.scanner-simulate-panel`, `.mock-cards-list`, `.mock-card-btn`, `.simulate-scan-btn`, `.simulate-label`, `.mock-card-icon`, `.mock-card-info` (mock card panel)
+- `.scanner-placeholder` with spinner (old loading state)
+
+**Add:**
+- `.scan-start-btn` — large centered button with camera icon, teal background (`#0f766e`), full-width
+- `.manual-cip-section` — input group with text field + submit button
+- `.cip-input` — text input styled to match existing dark theme, monospace font
+- `.cip-submit-btn` — teal button matching scan button style
+- `.pwa-notice` — info banner for browser users
+- `.scan-error-panel` — error state with icon and retry button
+
+### B5. No changes to other files
+
+- `HomeView.jsx` — "Scan TSI Card" button still navigates to ScannerView
+- `PublicView.jsx` — screen routing and `onSelectMedicine` handoff unchanged
+- `backend/server.js` — user handles `/api/tsi/:cip/prescriptions`
+- `capacitor.config.json` — no scanner-specific config needed
+
+---
+
+## Files Modified (summary)
+
+| File | Phase | Change |
+|---|---|---|
+| `package.json` | A1 | Bump all `@capacitor/*` to ^8.x |
+| `frontend/package.json` | B1 | Add `@capacitor-mlkit/barcode-scanning@^8.1.0` + `barcode-detector` |
+| `android/variables.gradle` | A2 | Update all 13 SDK/library versions |
+| `ios/App/Podfile` | A3 | iOS deployment target 13.0 → 15.0 |
+| `android/app/src/main/AndroidManifest.xml` | A4 | Add `density` to configChanges |
+| `android/build.gradle` | A5 | AGP 8.2.1 → 8.13.0, Google Services 4.4.0 → 4.4.4 |
+| `android/gradle/wrapper/gradle-wrapper.properties` | A5 | Gradle wrapper → 8.14.3 |
+| `frontend/src/views/ScannerView.jsx` | B3 | Full rewrite — real barcode scanning + manual input |
+| `frontend/src/views/ScannerView.css` | B4 | Remove old camera/mock styles, add new scan UI |
+
+---
+
+## Known Issues
+
+- **Android NullPointerException bug** (GitHub capawesome-team/capacitor-mlkit #160/#324) — affects `startScan()` in v8.0.1. Workaround: use `scan()` method (built-in native UI) instead of `startScan()` (custom WebView mode). Plan uses `scan()`, so this shouldn't hit us.
+- **`rawValue` can be undefined** in v8.x — handle with null check before CIP validation.
+- **Capacitor 8 requires Xcode 26+** — must have latest Xcode installed.
+- **Gradle 8.14.3 requires JDK 21+** — confirm JDK 21 is available.
+- **`@capacitor-mlkit/barcode-scanning` v6.x.x is deprecated** — this is why we upgrade to Capacitor 8 first (v8.x.x plugin requires Cap 8).
+
+---
+
+## Implementation Order
+
+| Step | Phase | Estimated Time |
+|---|---|---|
+| A1-A6 | Capacitor upgrade | ~30 min |
+| A7 | Verify build (Android + iOS) | ~30 min |
+| B1 | Install barcode plugin | ~5 min |
+| B3 | Rewrite ScannerView.jsx | ~2 hrs |
+| B4 | Update ScannerView.css | ~30 min |
+| B5 | Test on Android device | ~30 min |
+| B5 | Test on iOS device | ~30 min |
+
+Total: ~4-5 hours
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Patentes/MEMORIA_TECNICA.md b/Patentes/MEMORIA_TECNICA.md
new file mode 100644
index 0000000..6c02ce5
--- /dev/null
+++ b/Patentes/MEMORIA_TECNICA.md
@@ -0,0 +1,709 @@
+# Memoria tecnica FarmaFinder
+
+## 1. Resumen ejecutivo
+
+FarmaFinder es una aplicacion web/PWA para buscar medicamentos en la base oficial de CIMA (AEMPS), localizar farmacias que los comercializan y administrar el catalogo de farmacias y sus relaciones con medicamentos. La aplicacion tambien incluye perfil de usuario con ubicacion guardada, geocodificacion, ordenacion por distancia, estados de apertura de farmacias, notificaciones push para medicamentos y un panel de administracion para altas/bajas/importacion de farmacias.
+
+La base funcional actual esta repartida en cuatro capas principales:
+
+- `frontend/`: interfaz React + Vite, tambien preparada para PWA y empaquetado Capacitor.
+- `backend/`: API Express con sesion, autenticacion, persistencia SQLite/PG y notificaciones push.
+- `API/`: helpers de importacion y normalizacion de farmacias desde fuentes externas.
+- `android/` e `ios/`: shells nativos generados por Capacitor.
+
+## 2. Stack tecnologico
+
+### Frontend
+
+- React 18
+- Vite 5
+- Leaflet + React Leaflet para el mapa
+- Vitest + Testing Library + JSDOM para tests de UI
+- PWA con `vite-plugin-pwa`
+- Capacitor 6 para envoltorio nativo
+
+### Backend
+
+- Node.js en modo ESM
+- Express 4
+- SQLite como almacenamiento base local
+- PostgreSQL opcional para usuarios y sesiones cuando `PG_URL` esta definido
+- Redis para cache de CIMA
+- `express-session` para sesion de usuario
+- `bcrypt` para hash de contrasenas
+- `web-push` para notificaciones push web
+- `express-rate-limit` para proteccion de endpoints sensibles
+
+### Integraciones externas
+
+- CIMA API de la AEMPS para busqueda y detalle de medicamentos
+- Nominatim / OpenStreetMap para geocodificacion
+- OpenStreetMap Overpass u otras fuentes JSON para importacion de farmacias
+- Webhooks externos tipo n8n para importacion de farmacias
+
+## 3. Estructura del repositorio
+
+- `frontend/`: SPA principal
+- `backend/`: API principal y scripts de mantenimiento
+- `API/`: libreria de importacion de farmacias desde fuentes externas
+- `scraper/`: utilidades de scraping con Puppeteer
+- `android/` y `ios/`: proyectos nativos Capacitor
+- `docker-compose.yml`: entorno completo con backend, frontend, Redis y PostgreSQL
+
+## 4. Arquitectura funcional
+
+### Flujo publico
+
+1. El usuario escribe un medicamento en el buscador.
+2. El frontend llama a `GET /api/medicines/search`.
+3. El backend consulta CIMA, filtra resultados y los cachea en Redis.
+4. Al seleccionar un medicamento, el frontend llama a `GET /api/medicines/:id/pharmacies`.
+5. El backend devuelve farmacias enlazadas en SQLite/PG con precio, stock, coordenadas y horario.
+6. La UI permite ordenar por distancia si el usuario tiene ubicacion guardada o concede geolocalizacion.
+
+### Flujo de administracion
+
+1. Un admin inicia sesion.
+2. El panel permite gestionar farmacias, buscar medicamentos en CIMA e importar farmacias externas.
+3. El admin enlaza medicamentos a farmacias con precio y stock.
+4. Al crear un nuevo enlace de farmacia-medicamento, el backend dispara notificaciones push a usuarios suscritos.
+
+### Flujo de perfil y ubicacion
+
+1. Un usuario autenticado puede editar su perfil.
+2. Puede guardar direccion y coordenadas manualmente.
+3. Tambien puede geocodificar su direccion via Nominatim o usar la geolocalizacion del navegador.
+4. Esa ubicacion se usa en el ordenamiento por distancia en la vista publica.
+
+## 5. Frontend
+
+### Punto de entrada
+
+- `frontend/src/main.jsx` monta `` en `#root`.
+- Se inicializa el shell nativo con `initNativeShell()`.
+
+### Componente raiz
+
+`frontend/src/App.jsx` controla tres vistas:
+
+- `public`
+- `admin`
+- `profile`
+
+Tambien gestiona:
+
+- comprobacion de sesion con `GET /api/auth/check`
+- apertura/cierre del modal de login
+- cierre de sesion con `POST /api/auth/logout`
+- panel de notificaciones guardadas
+
+### Vistas principales
+
+#### PublicView
+
+`frontend/src/views/PublicView.jsx`
+
+Responsabilidades:
+
+- busqueda de medicamentos con debounce
+- consulta de farmacias asociadas al medicamento
+- mapa de farmacias
+- lista de farmacias con precio, stock, horario y notificaciones
+- ordenacion por distancia usando ubicacion guardada o geolocalizacion del navegador
+
+Caracteristicas clave:
+
+- Si el usuario tiene coordenadas en el perfil, se priorizan sobre la geolocalizacion del navegador.
+- La lista y el mapa usan la misma ordenacion.
+- Si no hay coordenadas o el navegador falla, se muestra un mensaje de error contextual.
+
+#### AdminView
+
+`frontend/src/views/AdminView.jsx`
+
+Responsabilidades:
+
+- autenticar acceso al panel
+- mostrar tabs de:
+ - farmacias
+ - medicamentos
+ - enlace farmacia-medicamento
+- logout de admin
+
+#### ProfileView
+
+`frontend/src/views/ProfileView.jsx`
+
+Responsabilidades:
+
+- editar direccion y coordenadas del usuario
+- geocodificar la direccion con `/api/geocode`
+- obtener ubicacion actual del dispositivo
+- abrir la vista de notificaciones guardadas
+- cerrar sesion
+
+## 6. Componentes de UI
+
+### Busqueda y resultados
+
+- `frontend/src/components/SearchBar.jsx`
+- `frontend/src/components/MedicineResults.jsx`
+- `frontend/src/components/PharmacyList.jsx`
+- `frontend/src/components/PharmacyMap.jsx`
+
+#### MedicineResults
+
+- Lista resultados de CIMA.
+- Cada card incluye boton de notificaciones para ese medicamento.
+- Al pulsar la card se abre el detalle de farmacias asociadas.
+
+#### PharmacyList
+
+- Muestra farmacias enlazadas al medicamento.
+- Incluye:
+ - distancia al usuario si existe ubicacion
+ - estado de apertura calculado a partir de `opening_hours`
+ - direccion
+ - telefono
+ - precio
+ - stock
+ - boton de notificacion por farmacia cuando el stock esta agotado
+
+#### PharmacyMap
+
+- Muestra farmacias sobre Leaflet.
+- Usa coordenadas de cada farmacia para ubicarlas en el mapa.
+
+### Admin components
+
+- `frontend/src/components/admin/PharmacyManagement.jsx`
+- `frontend/src/components/admin/MedicineManagement.jsx`
+- `frontend/src/components/admin/PharmacyMedicineLink.jsx`
+- `frontend/src/components/admin/LoginForm.jsx`
+
+#### PharmacyManagement
+
+- Lista farmacias existentes.
+- Permite crear, editar y borrar farmacias.
+- Integra importacion por:
+ - webhook externo
+ - OpenStreetMap / Overpass
+ - URL de open data JSON/GeoJSON
+- Permite filtrar farmacias por radio geografico.
+- Permite geocodificar una ciudad para obtener lat/lon/radio de trabajo.
+- Gestiona horario semanal estructurado.
+
+#### MedicineManagement
+
+- Busca medicamentos en CIMA desde el panel admin.
+- Solo sirve para exploracion y seleccion previa al enlace.
+
+#### PharmacyMedicineLink
+
+- Permite seleccionar farmacia y medicamento.
+- Crea o actualiza el enlace con precio y stock.
+- Permite editar y eliminar relaciones ya existentes.
+
+## 7. Utilidades de frontend
+
+### Geolocalizacion
+
+`frontend/src/utils/geo.js`
+
+- `haversineKm()`: calcula distancia entre dos puntos GPS.
+- `getUserPosition()`: obtiene ubicacion del navegador con validaciones de contexto seguro.
+- `formatDistance()`: da formato a metros/kilometros.
+
+### Horarios
+
+`frontend/src/utils/hours.js`
+
+- `getOpenStatus()`: interpreta el horario semanal y devuelve un estado legible.
+- Soporta:
+ - abierto
+ - cerrado
+ - abre a una hora concreta
+ - abre el siguiente dia habil
+- El formato almacenado es JSON con claves `sun`, `mon`, `tue`, `wed`, `thu`, `fri`, `sat`.
+
+### Notificaciones
+
+`frontend/src/utils/notifications.js`
+
+- comprueba soporte de Push API y Service Worker
+- obtiene la VAPID public key del backend
+- registra suscripciones push del navegador
+- guarda una huella local en `localStorage`
+- permite suscripcion global por medicamento o por medicamento + farmacia
+
+### Service worker
+
+`frontend/src/sw.js`
+
+- precache de assets PWA
+- muestra notificaciones al recibir eventos `push`
+- navega a la URL asociada al click en la notificacion
+
+## 8. Backend
+
+### Arranque
+
+`backend/server.js` es el nucleo de la API. Expone:
+
+- la aplicacion Express
+- `initDatabase()`
+- la conexion `db`
+
+Si `NODE_ENV !== test`, inicializa DB y levanta el servidor en `PORT` o `3001`.
+
+### Configuracion basica
+
+- CORS con credenciales
+- `express.json()`
+- session middleware
+- rate limiting en:
+ - busqueda
+ - login
+ - registro
+ - geocoding
+
+### Persistencia
+
+#### SQLite
+
+Se usa como base local principal:
+
+- farmacias
+- relaciones farmacia-medicamento
+- subscripciones push
+- fallback de usuarios cuando no hay PostgreSQL
+
+#### PostgreSQL opcional
+
+Si existe `PG_URL`, la tabla `users` y el store de sesiones se montan sobre PostgreSQL.
+
+Esto genera una arquitectura mixta:
+
+- SQLite para catalogo/relaciones
+- PostgreSQL para usuarios y sesiones, si se configura
+
+### Capa de sesion
+
+- `express-session`
+- store SQLite o PostgreSQL segun entorno
+- cookie httpOnly con maxAge de 24h
+- `trust proxy` configurable con `TRUST_PROXY`
+
+## 9. Modelo de datos
+
+### `pharmacies`
+
+Campos:
+
+- `id`
+- `name`
+- `address`
+- `phone`
+- `latitude`
+- `longitude`
+- `opening_hours`
+
+### `pharmacy_medicines`
+
+Relacion farmacia-medicamento.
+
+Campos:
+
+- `id`
+- `pharmacy_id`
+- `medicine_nregistro`
+- `medicine_name`
+- `price`
+- `stock`
+
+Restriccion:
+
+- `UNIQUE(pharmacy_id, medicine_nregistro)`
+
+### `users`
+
+Campos actuales:
+
+- `id`
+- `username`
+- `password_hash`
+- `is_admin`
+- `address`
+- `latitude`
+- `longitude`
+- `created_at`
+
+### `push_subscriptions`
+
+Subscripciones push globales por medicamento.
+
+Campos:
+
+- `id`
+- `medicine_nregistro`
+- `medicine_name`
+- `endpoint`
+- `p256dh`
+- `auth`
+- `user_id`
+- `created_at`
+
+### `push_subscriptions_pharmacy`
+
+Subscripciones push por medicamento y farmacia.
+
+Campos:
+
+- `id`
+- `medicine_nregistro`
+- `medicine_name`
+- `pharmacy_id`
+- `endpoint`
+- `p256dh`
+- `auth`
+- `user_id`
+- `created_at`
+
+## 10. API backend
+
+### Medicamentos
+
+- `GET /api/medicines/search?q=...`
+ - busca en CIMA con cache Redis
+ - devuelve una lista normalizada
+- `GET /api/medicines/:medicineId`
+ - devuelve detalle de un medicamento por `nregistro`
+- `GET /api/medicines/:medicineId/pharmacies`
+ - devuelve farmacias que tienen ese medicamento
+
+### Farmacias
+
+- `GET /api/pharmacies`
+ - lista completa de farmacias
+
+### Autenticacion
+
+- `POST /api/auth/login`
+- `POST /api/auth/register`
+- `POST /api/auth/logout`
+- `GET /api/auth/check`
+
+### Perfil
+
+- `GET /api/users/me`
+- `PUT /api/users/me`
+
+### Geocoding
+
+- `GET /api/geocode?q=...`
+ - autenticado
+ - usa Nominatim
+ - devuelve lat/lon y texto de resultado
+- `GET /api/admin/geocode?q=...`
+ - solo admin
+ - ademas calcula radio sugerido
+
+### Admin: farmacias
+
+- `POST /api/admin/pharmacies`
+- `PUT /api/admin/pharmacies/:id`
+- `DELETE /api/admin/pharmacies/:id`
+- `POST /api/admin/pharmacies/import-webhook`
+- `POST /api/admin/pharmacies/import-external`
+
+### Admin: medicamentos y relaciones
+
+- `GET /api/admin/medicines`
+- `GET /api/admin/pharmacies/:pharmacyId/medicines`
+- `POST /api/admin/pharmacy-medicines`
+- `PUT /api/admin/pharmacy-medicines/:id`
+- `DELETE /api/admin/pharmacy-medicines/:id`
+
+### Notificaciones
+
+- `GET /api/notifications/vapid-public-key`
+- `POST /api/notifications/subscribe`
+- `DELETE /api/notifications/unsubscribe`
+- `GET /api/notifications/mine`
+- `DELETE /api/notifications/mine`
+
+## 11. Capa de importacion externa
+
+La carpeta `API/` no expone un servidor HTTP propio, sino funciones reutilizables para importar farmacias desde distintas fuentes.
+
+### `API/index.js`
+
+- `fetchPharmaciesExternal(opts)`
+ - `source = 'osm'`
+ - `source = 'openData'`
+- decide el extractor adecuado segun la fuente
+
+### `API/normalize.js`
+
+- `buildAddressFromOsmTags()`
+- `osmElementToPharmacy()`
+- normaliza nodos Overpass a un formato comun de farmacia
+- parsea horarios OSM si existen
+
+### `API/opening-hours-osm.js`
+
+- parser de un subconjunto de `opening_hours`
+- soporta:
+ - `24/7`
+ - rangos semanales
+ - dias multiples
+ - `off` / `closed`
+ - franjas partidas resumidas
+
+### `backend/farmacias-webhook-import.js`
+
+- importa datos desde un webhook HTTP
+- normaliza campos en espanol o ingles
+- acepta ubicacion en distintas variantes
+- extrae horarios si vienen en formato OSM
+- inserta o salta duplicados con estadisticas
+
+## 12. CIMA y cache
+
+`backend/cima-service.js` implementa la integracion con CIMA.
+
+### Busqueda
+
+- consulta `https://cima.aemps.es/cima/rest/medicamentos`
+- usa el parametro `nombre`
+- normaliza el resultado a campos internos:
+ - `id`
+ - `nregistro`
+ - `name`
+ - `active_ingredient`
+ - `dosage`
+ - `form`
+ - `formSimplified`
+ - `laboratory`
+ - `prescription`
+ - `commercialized`
+ - `generic`
+ - `photos`
+ - `docs`
+
+### Detalle
+
+- consulta `GET /medicamento/:nregistro`
+- cachea por mas tiempo que la busqueda
+
+### Cache
+
+- Redis guarda resultados de busqueda y detalle
+- si CIMA falla, se intenta devolver cache obsoleto si existe
+
+## 13. Notificaciones push
+
+### Estado actual
+
+La app ya soporta notificaciones push web completas.
+
+### Backend
+
+- usa VAPID si `VAPID_PUBLIC_KEY` y `VAPID_PRIVATE_KEY` existen
+- si faltan, push queda desactivado con respuesta `503`
+- al crear una relacion nueva farmacia-medicamento, se ejecuta `sendPushForMedicine()`
+- se deduplican endpoints para evitar notificacion doble global + farmacia
+- si el endpoint devuelve `404` o `410`, la suscripcion se limpia
+
+### Frontend
+
+- permite suscripcion global por medicamento
+- permite suscripcion por medicamento + farmacia
+- el icono de campana refleja el estado local
+- la vista `Saved notifications` permite ver y borrar suscripciones guardadas del usuario
+
+## 14. PWA y capa nativa
+
+### PWA
+
+- existe `frontend/src/sw.js`
+- hay assets publicos de icono
+- la app esta pensada para funcionar como PWA instalable
+
+### Capacitor
+
+- `capacitor.config.json`
+- `android/`
+- `ios/`
+
+El proyecto esta preparado para empaquetarse como app nativa. La documentacion de `NATIVE.md` indica que no hay una base de codigo separada para Android e iOS; la UI real vive en `frontend/`.
+
+## 15. Scripts y comandos
+
+### Raiz
+
+- `npm run dev`: backend + frontend en paralelo
+- `npm run start`: backend + preview frontend
+- `npm run install:all`: instala dependencias raiz, backend y frontend
+- `npm run build:web`: build de frontend
+- `npm run cap:sync`: build web + sync Capacitor
+
+### Backend
+
+- `npm start`
+- `npm run dev`
+- `npm run seed`
+- `npm run create-admin`
+- `npm run migrate`
+- `npm run import-farmacias`
+- `npm test`
+
+### Frontend
+
+- `npm run dev`
+- `npm run build`
+- `npm run preview`
+- `npm run test`
+
+## 16. Docker
+
+`docker-compose.yml` levanta:
+
+- `redis`
+- `postgres`
+- `backend`
+- `frontend`
+
+Puertos:
+
+- frontend: `3000`
+- backend: `3001`
+
+Persistencia:
+
+- `backend_data` para la DB SQLite del backend
+- `postgres_data` para PostgreSQL
+
+## 17. Variables de entorno
+
+### Backend
+
+- `PORT`
+- `SESSION_SECRET`
+- `CORS_ORIGIN`
+- `FARMACIAS_WEBHOOK_URL`
+- `REDIS_HOST`
+- `REDIS_PORT`
+- `REDIS_PASSWORD`
+- `DATABASE_PATH`
+- `PG_URL`
+- `TRUST_PROXY`
+- `VAPID_PUBLIC_KEY`
+- `VAPID_PRIVATE_KEY`
+- `VAPID_SUBJECT`
+- `NODE_ENV`
+
+### App
+
+- en produccion, el frontend debe poder resolver la URL del backend segun despliegue
+- en native shell, el manual `NATIVE.md` indica que conviene usar URL absoluta o servir el PWA desplegado
+
+## 18. Seeds, migraciones y administracion
+
+### `backend/seed.js`
+
+- crea tablas basicas
+- inserta farmacias y medicamentos de ejemplo
+- genera relaciones ficticias usando `EXAMPLE_...`
+- actualmente es util para demos, no como dato real
+
+### `backend/create-admin.js`
+
+- crea usuario admin en SQLite o PostgreSQL segun `PG_URL`
+- por defecto:
+ - usuario: `admin`
+ - password: `admin123`
+
+### `backend/migrate.js`
+
+- migracion para el cambio historico de `medicine_id` a `medicine_nregistro`
+- la tabla `medicines` antigua se conserva como referencia si existe
+
+## 19. Tests
+
+### Backend
+
+- `backend/__tests__/server.test.js`
+ - valida busqueda vacia
+ - valida login incorrecto
+ - valida proteccion de rutas admin
+ - valida creacion de farmacia autenticado
+- `backend/__tests__/opening-hours-osm.test.js`
+ - cubre parser de horarios OSM
+
+### Frontend
+
+- existe configuracion de Vitest
+- hay `frontend/src/App.test.jsx`
+- la cobertura visible en el repo parece enfocada a smoke tests y utilidades
+
+## 20. Observaciones tecnicas y limites actuales
+
+1. El backend mezcla SQLite y PostgreSQL segun entorno. Esto funciona, pero introduce dos rutas de persistencia para usuarios y sesiones.
+2. Los medicamentos no se guardan localmente como catalogo propio; se consumen desde CIMA en tiempo real y se cachean en Redis.
+3. Los enlaces farmacia-medicamento dependen de `nregistro` de CIMA, no de un ID interno de medicamentos.
+4. Las notificaciones push son web push; en shells nativos siguen la logica del navegador/PWA, no una integracion FCM/APNs independiente.
+5. La importacion de farmacias depende de la calidad de la fuente externa y de la normalizacion de campos.
+6. El seed actual contiene datos de ejemplo y relaciones ficticias; no representa datos de produccion.
+
+## 21. Conclusiones
+
+El estado actual de FarmaFinder es el de una plataforma funcional orientada a consulta y administracion de farmacias y medicamentos, con un backend ya bastante consolidado: autentica usuarios, controla roles, persiste relaciones, geocodifica, importa fuentes externas, cachea CIMA y dispara push notifications. La parte de frontend acompana ese backend con un flujo publico de busqueda, un perfil con ubicacion y un panel admin operativo.
+
+Si quieres, el siguiente paso puede ser convertir esta memoria en una version formal de entrega, con estilo academico o empresarial, o bien en un documento mas tecnico con diagramas de arquitectura y secuencia.
+
+## 22. Next steps propuestos
+
+El siguiente paso funcional natural para FarmaFinder seria incorporar el escaneo de la TSI, de forma que el usuario pueda identificar rapidamente su perfil asistencial y, a partir de ahi, cruzar su necesidad con el stock real disponible en farmacias.
+
+### Objetivo
+
+- Capturar la informacion de la tarjeta sanitaria individual mediante escaneo.
+- Asociar esa informacion al perfil del usuario de manera segura.
+- Recuperar o inferir los medicamentos relevantes para el usuario.
+- Contrastar esos medicamentos con el stock de farmacias cercanas.
+- Permitir actuar si no hay stock disponible, por ejemplo:
+ - reservar una farmacia concreta
+ - generar una solicitud de pedido
+ - iniciar un flujo de aviso o sustitucion
+
+### Flujo funcional propuesto
+
+1. El usuario abre el escaner de TSI desde la app.
+2. La app lee la tarjeta y extrae los identificadores necesarios.
+3. El backend valida la informacion y la vincula al usuario autenticado.
+4. Se obtiene la lista de medicamentos asociados o derivados del contexto del usuario.
+5. El sistema cruza esa lista con:
+ - farmacias cercanas
+ - stock disponible
+ - precio
+ - horario
+6. Si no existe stock suficiente, la app muestra alternativas y acciones posibles.
+
+### Consideraciones tecnicas
+
+- Esta funcionalidad requiere definir el formato exacto de lectura de la TSI y las fuentes de datos sanitarias a consultar.
+- Debe tratarse como una funcionalidad sensible, con control de acceso estricto y minimizacion de datos.
+- El escaneo deberia integrarse con el mismo modelo de ubicacion, autenticacion y notificaciones que ya existe.
+- La logica de contraste stock/medicamento encaja bien con el modelo actual de `pharmacy_medicines`, pero probablemente exigiria ampliar la capa de negocio para soportar reservas, pedidos o estados intermedios.
+
+### Riesgos y dependencias
+
+- Dependencia de la integracion real con sistemas sanitarios externos.
+- Posible necesidad de cumplimiento legal adicional por el tipo de dato tratado.
+- Definicion de si el sistema solo informa de disponibilidad o si tambien permite operar pedidos/reservas.
+- Necesidad de auditar trazabilidad, consentimiento y control de uso de datos.
+
+### Resultado esperado
+
+Esta ampliacion convertiria FarmaFinder de un buscador de disponibilidad a un asistente operativo de acceso al medicamento, capaz de ayudar al usuario a pasar de la consulta del stock a la accion cuando no exista disponibilidad inmediata.
diff --git a/Patentes/PRECONVERSION_OEPM_FARMAFINDER.pdf b/Patentes/PRECONVERSION_OEPM_FARMAFINDER.pdf
new file mode 100644
index 0000000..2c4b756
--- /dev/null
+++ b/Patentes/PRECONVERSION_OEPM_FARMAFINDER.pdf
@@ -0,0 +1,95 @@
+%PDF-1.4
+1 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >>
+endobj
+2 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Bold /Encoding /WinAnsiEncoding >>
+endobj
+3 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >>
+endobj
+4 0 obj
+<< /Length 645 >>
+stream
+BT /F2 18 Tf 126 783.89 Td (DOCUMENTO DE PRECONVERSION) Tj ET
+BT /F1 12 Tf 111 754.85 Td (Oficina Espaola de Patentes y Marcas \(OEPM\)) Tj ET
+BT /F3 12 Tf 136 723.49 Td (Hoja de preparacion para expediente de patente) Tj ET
+0.8 w 56 630.13 483.28 66 re S
+BT /F1 11 Tf 66 696.13 Td (Solicitante: Antoni Nuez Romeu) Tj ET
+BT /F1 11 Tf 66 682.05 Td (DNI/NIF: 45858029P) Tj ET
+BT /F1 11 Tf 66 667.9699999999999 Td (Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221) Tj ET
+BT /F1 11 Tf 66 653.8899999999999 Td (Inventor: Antoni Nuez Romeu) Tj ET
+BT /F3 10 Tf 126 631.8099999999998 Td (Documento de apoyo para expediente de patente) Tj ET
+endstream
+endobj
+5 0 obj
+<< /Length 3202 >>
+stream
+BT /F2 13 Tf 56 783.89 Td (1. Identificacion del expediente) Tj ET
+0.2 w 56 763.25 m 539.28 763.25 l S
+BT /F1 11.2 Tf 56 753.25 Td (Solicitante: Antoni Nuez Romeu) Tj ET
+BT /F1 11.2 Tf 56 737.914 Td (NIF/NIE/DNI: 45858029P) Tj ET
+BT /F1 11.2 Tf 56 722.578 Td (Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221) Tj ET
+BT /F1 11.2 Tf 56 707.242 Td (Titulo de la invencion: Sistema y procedimiento implementados por ordenador para) Tj ET
+BT /F1 11.2 Tf 56 692.906 Td (la identificacion de necesidades terapeuticas mediante escaneo de tarjeta) Tj ET
+BT /F1 11.2 Tf 56 678.5699999999999 Td (sanitaria individual, contraste con stock farmacutico geolocalizado y generacion) Tj ET
+BT /F1 11.2 Tf 56 664.2339999999999 Td (de acciones de suministro.) Tj ET
+BT /F2 13 Tf 56 648.8979999999999 Td (2. Objeto de este documento) Tj ET
+0.2 w 56 628.2579999999999 m 539.28 628.2579999999999 l S
+BT /F1 11.2 Tf 56 618.2579999999999 Td (Este documento se emite como hoja interna de preparacion y control del expediente) Tj ET
+BT /F1 11.2 Tf 56 603.9219999999999 Td (antes de su presentacion ante la Oficina Espaola de Patentes y Marcas \(OEPM\). Su) Tj ET
+BT /F1 11.2 Tf 56 589.5859999999999 Td (finalidad es reunir en un unico soporte los datos de identificacion, la referencia) Tj ET
+BT /F1 11.2 Tf 56 575.2499999999999 Td (del objeto tecnico y la declaracion de que la documentacion principal del) Tj ET
+BT /F1 11.2 Tf 56 560.9139999999999 Td (expediente ha sido preparada para su presentacion.) Tj ET
+BT /F2 13 Tf 56 545.5779999999999 Td (3. Contenido del expediente) Tj ET
+0.2 w 56 524.9379999999999 m 539.28 524.9379999999999 l S
+BT /F1 11.1 Tf 64 514.9379999999999 Td (" Solicitud de patente.) Tj ET
+BT /F1 11.1 Tf 64 500.72999999999985 Td (" Memoria descriptiva.) Tj ET
+BT /F1 11.1 Tf 64 486.5219999999998 Td (" Reivindicaciones.) Tj ET
+BT /F1 11.1 Tf 64 472.3139999999998 Td (" Resumen.) Tj ET
+BT /F1 11.1 Tf 64 458.10599999999977 Td (" Anexo de dibujos.) Tj ET
+BT /F1 11.1 Tf 64 443.89799999999974 Td (" Solicitud de reduccion de tasas para persona fisica.) Tj ET
+BT /F2 13 Tf 56 429.6899999999997 Td (4. Declaracion) Tj ET
+0.2 w 56 409.0499999999997 m 539.28 409.0499999999997 l S
+BT /F1 11.2 Tf 56 399.0499999999997 Td (El solicitante declara que la documentacion aportada se corresponde con una unica) Tj ET
+BT /F1 11.2 Tf 56 384.7139999999997 Td (invencion, que la descripcion y las reivindicaciones han sido redactadas de forma) Tj ET
+BT /F1 11.2 Tf 56 370.3779999999997 Td (coherente y que el material adjunto se presenta a efectos de tramitacion ante la) Tj ET
+BT /F1 11.2 Tf 56 356.0419999999997 Td (OEPM.) Tj ET
+BT /F2 13 Tf 56 340.7059999999997 Td (5. Firma) Tj ET
+0.2 w 56 320.0659999999997 m 539.28 320.0659999999997 l S
+BT /F1 11.2 Tf 56 310.0659999999997 Td (En Terrassa, a 22 de junio de 2026.) Tj ET
+BT /F1 11.2 Tf 56 294.7299999999997 Td (Fdo.: Antoni Nuez Romeu) Tj ET
+BT /F1 11.2 Tf 56 279.39399999999966 Td (DNI/NIF: 45858029P) Tj ET
+BT /F1 11.2 Tf 56 264.05799999999965 Td (Documento de apoyo interno. Revisar con agente de propiedad industrial antes de) Tj ET
+BT /F1 11.2 Tf 56 249.72199999999964 Td (presentar.) Tj ET
+BT /F1 9 Tf 495.28 234.38599999999963 Td (Pagina 2) Tj ET
+endstream
+endobj
+6 0 obj
+<< /Type /Pages /Kids [7 0 R 8 0 R] /Count 2 >>
+endobj
+7 0 obj
+<< /Type /Page /Parent 6 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 4 0 R >>
+endobj
+8 0 obj
+<< /Type /Page /Parent 6 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 5 0 R >>
+endobj
+9 0 obj
+<< /Type /Catalog /Pages 6 0 R >>
+endobj
+xref
+0 10
+0000000000 65535 f
+0000000009 00000 n
+0000000108 00000 n
+0000000206 00000 n
+0000000306 00000 n
+0000001002 00000 n
+0000004256 00000 n
+0000004319 00000 n
+0000004471 00000 n
+0000004623 00000 n
+trailer << /Size 10 /Root 9 0 R >>
+startxref
+4672
+%%EOF
diff --git a/Patentes/REDUCCION_TASAS_OEPM_PERSONA_FISICA.pdf b/Patentes/REDUCCION_TASAS_OEPM_PERSONA_FISICA.pdf
new file mode 100644
index 0000000..982f011
--- /dev/null
+++ b/Patentes/REDUCCION_TASAS_OEPM_PERSONA_FISICA.pdf
@@ -0,0 +1,92 @@
+%PDF-1.4
+1 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >>
+endobj
+2 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Bold /Encoding /WinAnsiEncoding >>
+endobj
+3 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >>
+endobj
+4 0 obj
+<< /Length 618 >>
+stream
+BT /F2 18 Tf 126 783.89 Td (SOLICITUD DE REDUCCION DE TASAS) Tj ET
+BT /F1 12 Tf 111 754.85 Td (Oficina Espaola de Patentes y Marcas \(OEPM\)) Tj ET
+BT /F3 12 Tf 136 723.49 Td (Persona fisica) Tj ET
+0.8 w 56 630.13 483.28 66 re S
+BT /F1 11 Tf 66 696.13 Td (Solicitante: Antoni Nuez Romeu) Tj ET
+BT /F1 11 Tf 66 682.05 Td (DNI/NIF: 45858029P) Tj ET
+BT /F1 11 Tf 66 667.9699999999999 Td (Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221) Tj ET
+BT /F1 11 Tf 66 653.8899999999999 Td (Inventor: Antoni Nuez Romeu) Tj ET
+BT /F3 10 Tf 126 631.8099999999998 Td (Documento de apoyo para expediente de patente) Tj ET
+endstream
+endobj
+5 0 obj
+<< /Length 3068 >>
+stream
+BT /F2 13 Tf 56 783.89 Td (1. Datos del solicitante) Tj ET
+0.2 w 56 763.25 m 539.28 763.25 l S
+BT /F1 11.2 Tf 56 753.25 Td (Nombre y apellidos: Antoni Nuez Romeu) Tj ET
+BT /F1 11.2 Tf 56 737.914 Td (DNI/NIF: 45858029P) Tj ET
+BT /F1 11.2 Tf 56 722.578 Td (Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221) Tj ET
+BT /F2 13 Tf 56 707.242 Td (2. Expediente al que se refiere) Tj ET
+0.2 w 56 686.602 m 539.28 686.602 l S
+BT /F1 11.2 Tf 56 676.602 Td (Titulo de la invencion: Sistema y procedimiento implementados por ordenador para) Tj ET
+BT /F1 11.2 Tf 56 662.266 Td (la identificacion de necesidades terapeuticas mediante escaneo de tarjeta) Tj ET
+BT /F1 11.2 Tf 56 647.93 Td (sanitaria individual, contraste con stock farmacutico geolocalizado y generacion) Tj ET
+BT /F1 11.2 Tf 56 633.5939999999999 Td (de acciones de suministro.) Tj ET
+BT /F2 13 Tf 56 618.2579999999999 Td (3. Solicitud) Tj ET
+0.2 w 56 597.6179999999999 m 539.28 597.6179999999999 l S
+BT /F1 11.2 Tf 56 587.6179999999999 Td (Por medio del presente escrito, el solicitante, en su condicion de persona fisica,) Tj ET
+BT /F1 11.2 Tf 56 573.2819999999999 Td (solicita que se le aplique la reduccion de tasas que resulte procedente conforme a) Tj ET
+BT /F1 11.2 Tf 56 558.9459999999999 Td (la normativa vigente de la Oficina Espaola de Patentes y Marcas \(OEPM\) para) Tj ET
+BT /F1 11.2 Tf 56 544.6099999999999 Td (personas fisicas.) Tj ET
+BT /F1 11.2 Tf 56 529.2739999999999 Td (A tal efecto, manifiesta que la solicitud de patente se presenta a su nombre como) Tj ET
+BT /F1 11.2 Tf 56 514.9379999999999 Td (persona fisica y pide que la oficina tramite esta peticion de conformidad con los) Tj ET
+BT /F1 11.2 Tf 56 500.60199999999986 Td (requisitos y porcentajes de reduccion establecidos en la normativa aplicable al) Tj ET
+BT /F1 11.2 Tf 56 486.26599999999985 Td (momento de la presentacion.) Tj ET
+BT /F2 13 Tf 56 470.92999999999984 Td (4. Declaracion responsable) Tj ET
+0.2 w 56 450.28999999999985 m 539.28 450.28999999999985 l S
+BT /F1 11.2 Tf 56 440.28999999999985 Td (El solicitante declara bajo su responsabilidad que los datos consignados en este) Tj ET
+BT /F1 11.2 Tf 56 425.95399999999984 Td (documento son ciertos y que aportara, en su caso, la documentacion adicional que) Tj ET
+BT /F1 11.2 Tf 56 411.6179999999998 Td (la OEPM pudiera requerir para acreditar la condicion de persona fisica y la) Tj ET
+BT /F1 11.2 Tf 56 397.2819999999998 Td (procedencia de la reduccion solicitada.) Tj ET
+BT /F2 13 Tf 56 381.9459999999998 Td (5. Firma) Tj ET
+0.2 w 56 361.3059999999998 m 539.28 361.3059999999998 l S
+BT /F1 11.2 Tf 56 351.3059999999998 Td (En Terrassa, a 22 de junio de 2026.) Tj ET
+BT /F1 11.2 Tf 56 335.9699999999998 Td (Fdo.: Antoni Nuez Romeu) Tj ET
+BT /F1 11.2 Tf 56 320.6339999999998 Td (DNI/NIF: 45858029P) Tj ET
+BT /F1 11.2 Tf 56 305.2979999999998 Td (Nota: revisar con agente o con la OEPM el formulario exacto y los requisitos) Tj ET
+BT /F1 11.2 Tf 56 290.96199999999976 Td (vigentes antes de presentar.) Tj ET
+BT /F1 9 Tf 495.28 275.62599999999975 Td (Pagina 2) Tj ET
+endstream
+endobj
+6 0 obj
+<< /Type /Pages /Kids [7 0 R 8 0 R] /Count 2 >>
+endobj
+7 0 obj
+<< /Type /Page /Parent 6 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 4 0 R >>
+endobj
+8 0 obj
+<< /Type /Page /Parent 6 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 5 0 R >>
+endobj
+9 0 obj
+<< /Type /Catalog /Pages 6 0 R >>
+endobj
+xref
+0 10
+0000000000 65535 f
+0000000009 00000 n
+0000000108 00000 n
+0000000206 00000 n
+0000000306 00000 n
+0000000975 00000 n
+0000004095 00000 n
+0000004158 00000 n
+0000004310 00000 n
+0000004462 00000 n
+trailer << /Size 10 /Root 9 0 R >>
+startxref
+4511
+%%EOF
diff --git a/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.html b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.html
new file mode 100644
index 0000000..2cc95cc
--- /dev/null
+++ b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.html
@@ -0,0 +1,288 @@
+
+
+
Oficina: Oficina Española de Patentes y Marcas (OEPM)
+
Título de la invención:
+ Sistema y procedimiento implementados por ordenador para la identificación de necesidades terapéuticas mediante escaneo de tarjeta sanitaria individual, contraste con stock farmacéutico geolocalizado y generación de acciones de suministro.
+
+
+
+
Solicitante: Antoni Nuñez Romeu
+
NIF/CIF: 45858029P
+
Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221
+
Inventor o inventores: Antoni Nuñez Romeu
+
+
+
+
+
+
+
1. Campo técnico de la invención
+
+
La invención se encuadra en los sistemas informáticos aplicados al sector sanitario y farmacéutico, en particular en soluciones de captura de identificadores sanitarios, comparación automatizada de disponibilidad de medicamentos y asistencia digital a la dispensación y suministro.
+
+
+
2. Antecedentes de la invención
+
+
Las soluciones actuales de búsqueda de medicamentos y farmacias permiten localizar productos y mostrar stock aproximado, pero normalmente operan a partir de una búsqueda manual por nombre de medicamento o principio activo. También existen sistemas de geolocalización y de gestión de inventario, pero suelen estar desacoplados del contexto sanitario del usuario y no integran, en una única cadena técnica, la identificación mediante tarjeta sanitaria individual, la inferencia de necesidades terapéuticas y la comparación en tiempo real con disponibilidad farmacéutica local.
+
Además, cuando no existe stock en la farmacia más próxima, el usuario debe iniciar manualmente nuevos procesos de búsqueda o desplazamiento, sin que el sistema proponga de forma automatizada acciones técnicas de reserva, pedido o derivación basadas en la disponibilidad real.
+
+
+
3. Problema técnico a resolver
+
+
La invención resuelve el problema técnico de reducir el tiempo y la fricción entre la identificación de una necesidad terapéutica y la localización de una farmacia que disponga del medicamento adecuado, integrando:
+
+
lectura segura de identificadores sanitarios,
+
obtención de referencias de medicamento asociadas,
+
comparación automatizada con inventarios de farmacias,
+
priorización por proximidad y disponibilidad,
+
generación de acciones técnicas de suministro cuando no exista stock inmediato.
+
+
+
+
4. Resumen de la invención
+
+
La invención propone un sistema y procedimiento implementados por ordenador que operan sobre un terminal móvil o dispositivo de lectura. El sistema captura la información de una tarjeta sanitaria individual mediante escaneo, valida la información mediante un módulo de verificación, asocia el resultado al perfil del usuario autenticado y obtiene una lista de medicamentos o necesidades terapéuticas relevantes. Posteriormente, un motor de contraste consulta un repositorio de stock de farmacias geolocalizadas y determina la coincidencia entre la necesidad detectada y la disponibilidad real en cada establecimiento. Si existe stock, el sistema prioriza las farmacias adecuadas y presenta una ruta de acceso o reserva. Si no existe stock, el sistema genera automáticamente una acción de aviso, pedido, reserva o derivación, conservando trazabilidad técnica del evento. La invención no se limita a una búsqueda manual, sino que integra captura, validación, georreferenciación, consulta de stock y respuesta automática en una única arquitectura técnica.
+
+
+
+
+
5. Breve descripción de los dibujos
+
+
Figura 1. Diagrama de bloques general del sistema.
+
Figura 2. Flujo de captura y validación del escaneo de la TSI.
+
Figura 3. Flujo de contraste entre necesidad terapéutica y stock de farmacias.
+
Figura 4. Flujo de acción cuando no existe stock disponible.
+
+
+
6. Descripción detallada de la invención
+
6.1 Arquitectura general
+
+
El sistema comprende al menos los siguientes módulos:
+
+
un módulo de captura de imagen o lectura óptica para escanear la tarjeta sanitaria individual;
+
un módulo de extracción de datos para identificar los campos relevantes de la tarjeta;
+
un módulo de verificación de identidad y autorización, vinculado al usuario autenticado;
+
un módulo de obtención de necesidades terapéuticas o medicamentos asociados;
+
un módulo de geolocalización para obtener la posición del usuario o una posición de referencia;
+
un módulo de consulta de inventario para recuperar stock, precio y horario de farmacias;
+
un módulo de contraste y priorización para ordenar farmacias según disponibilidad y cercanía;
+
un módulo de generación de acciones para crear reserva, aviso, pedido o derivación;
+
un módulo de trazabilidad y auditoría.
+
+
+
+
6.2 Funcionamiento
+
+
En una realización preferida, el usuario abre la aplicación y solicita el escaneo de su tarjeta sanitaria individual. El terminal captura la imagen o el código de la tarjeta y el módulo de extracción identifica los datos técnicos necesarios para enlazar el contexto sanitario del usuario con un conjunto de medicamentos o referencias de tratamiento.
+
El sistema valida que la operación se ejecuta sobre un usuario autenticado y autorizado. A continuación, el motor de contraste consulta el inventario de farmacias cercanas, recuperando para cada farmacia al menos su ubicación, horario, stock y, opcionalmente, precio.
+
El módulo de priorización calcula una orden de resultados en base a criterios técnicos tales como:
+
+
existencia de stock,
+
nivel de stock,
+
distancia geográfica,
+
horario de apertura,
+
capacidad de reserva o solicitud de pedido.
+
+
Cuando existe disponibilidad, el sistema muestra una lista priorizada de farmacias y puede iniciar una reserva o una indicación de recogida. Cuando no existe disponibilidad, el sistema no se limita a informar de la falta de stock, sino que genera una acción técnica adicional, por ejemplo:
+
+
alerta a la farmacia seleccionada,
+
solicitud de pedido a distribución o proveedor,
+
derivación automática a otra farmacia con stock,
+
registro de una lista de espera o interés de suministro.
+
+
+
+
6.3 Tratamiento de datos y seguridad
+
+
La invención prevé que la información derivada del escaneo de la TSI se trate con medidas de minimización de datos, control de acceso, cifrado en tránsito y registro de eventos. El sistema no expone innecesariamente los datos de la tarjeta sanitaria y solo conserva los elementos imprescindibles para la operación descrita.
+
+
+
6.4 Integración con la plataforma FarmaFinder
+
+
En una implementación concreta, el sistema puede integrarse con una plataforma que ya disponga de:
+
+
catálogo de farmacias,
+
geolocalización,
+
stock por medicamento,
+
autenticación de usuario,
+
notificaciones push,
+
histórico de acciones y preferencias.
+
+
La integración permite que el resultado del escaneo de la TSI no se limite a una consulta pasiva, sino que se convierta en un disparador de decisiones técnicas sobre disponibilidad y suministro.
+
+
+
+
+
7. Ejemplo de realización
+
+
+
El usuario inicia sesión en la aplicación.
+
El usuario escanea su TSI con la cámara del terminal.
+
El sistema extrae el identificador necesario y lo vincula al perfil autorizado.
+
El motor terapéutico asocia una necesidad de medicamento o tratamiento.
+
El sistema consulta farmacias cercanas con stock del medicamento.
+
Si hay stock, ordena las farmacias por proximidad y disponibilidad.
+
Si no hay stock, genera una reserva, una alerta o una solicitud de pedido.
+
+
+
+
8. Reivindicaciones
+
+
+
Reivindicación 1. Sistema implementado por ordenador para identificar una necesidad terapéutica a partir del escaneo de una tarjeta sanitaria individual, caracterizado porque comprende medios de captura para obtener datos de la tarjeta sanitaria individual; medios de verificación para asociar dichos datos a un usuario autenticado; medios de obtención de una referencia de medicamento o necesidad terapéutica; medios de consulta de inventario para recuperar stock de farmacias geolocalizadas; medios de contraste para comparar la referencia de medicamento o necesidad terapéutica con el stock disponible; y medios de generación de acciones para producir una reserva, aviso, pedido o derivación cuando el stock disponible sea insuficiente.
+
+
+
Reivindicación 2. Sistema según la reivindicación 1, en el que los medios de consulta de inventario ordenan las farmacias según una combinación de stock disponible, proximidad geográfica y horario de apertura.
+
+
+
Reivindicación 3. Sistema según cualquiera de las reivindicaciones anteriores, en el que los datos de la tarjeta sanitaria individual son tratados mediante un módulo de minimización y cifrado para limitar su almacenamiento a los campos técnicamente necesarios.
+
+
+
Reivindicación 4. Sistema según cualquiera de las reivindicaciones anteriores, en el que la generación de acciones comprende la creación de una reserva, la emisión de una notificación a la farmacia o la solicitud de pedido a un circuito de suministro.
+
+
+
Reivindicación 5. Sistema según cualquiera de las reivindicaciones anteriores, en el que la comparación de stock se realiza contra un repositorio de farmacias enlazadas con medicamentos mediante un identificador de registro farmacológico.
+
+
+
Reivindicación 6. Sistema según cualquiera de las reivindicaciones anteriores, en el que la geolocalización del usuario se obtiene a partir de coordenadas almacenadas en un perfil autenticado o a partir del dispositivo de lectura.
+
+
+
Reivindicación 7. Procedimiento implementado por ordenador para asistir en la localización y suministro de medicamentos, caracterizado porque comprende escanear una tarjeta sanitaria individual; verificar la autorización del usuario; derivar una necesidad terapéutica o referencia de medicamento; consultar stock de farmacias geolocalizadas; comparar la necesidad con el stock disponible; y generar una acción técnica de reserva, aviso, pedido o derivación cuando no exista disponibilidad suficiente.
+
+
+
Reivindicación 8. Procedimiento según la reivindicación 7, en el que la comparación y priorización se ejecutan en tiempo real o cuasi tiempo real durante la interacción del usuario con la aplicación.
+
+
+
Reivindicación 9. Dispositivo móvil, terminal o sistema de lectura que comprende una cámara o lector óptico y que está configurado para ejecutar el sistema de cualquiera de las reivindicaciones 1 a 6.
+
+
+
+
+
+
9. Aplicación industrial
+
+
La invención es susceptible de aplicación industrial en plataformas de asistencia farmacéutica, sistemas de gestión de inventario, servicios de reserva o pedido de medicamentos y terminales de consulta sanitaria.
+
+
+
10. Resumen
+
+
La presente invención se refiere a un sistema y procedimiento implementados por ordenador que permiten, a partir del escaneo de una tarjeta sanitaria individual mediante un terminal móvil o dispositivo equivalente, asociar de forma segura un contexto de paciente a una necesidad terapéutica, obtener una referencia de medicamentos relevantes, comparar dicha necesidad con el stock disponible en farmacias geolocalizadas y generar, en caso de falta de disponibilidad, una acción de reserva, aviso, solicitud de pedido o derivación a una farmacia alternativa. El sistema integra captura de datos, verificación de identidad, geolocalización, consulta de disponibilidad, gestión de stock y generación de eventos de suministro en una única cadena técnica de procesamiento.
+
+
+
11. Notas para presentación en OEPM
+
11. Anexo de dibujos
+
+
Las figuras indicadas en la presente memoria tienen carácter esquemático y se incorporan a efectos ilustrativos de la arquitectura, del flujo de captura, del contraste de stock y de la generación de acciones. En una presentación definitiva, dichas figuras podrán acompañarse como láminas separadas numeradas de forma consecutiva.
+
+
+
12. Firma del solicitante
+
+
En Terrassa, a 22 de junio de 2026.
+
Fdo.: Antoni Nuñez Romeu
+
DNI/NIF: 45858029P
+
+
+
13. Notas para presentación en OEPM
+
+
+
La solicitud debe presentarse como una única invención o un único concepto inventivo general.
+
La descripción, reivindicaciones y dibujos deben ser coherentes entre sí.
+
La protección en patente debe apoyarse en un efecto técnico concreto y no en una mera regla comercial o método abstracto.
+
Esta redacción evita formular una reivindicación independiente de "programa de ordenador como tal" y se centra en un sistema y un procedimiento implementados por ordenador con interacción técnica sobre captura, contraste de inventario y generación de acciones.
+
Antes de presentar la solicitud conviene una búsqueda de anterioridades y una revisión por agente de propiedad industrial.
+
+
+
+
+
diff --git a/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.md b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.md
new file mode 100644
index 0000000..24bff40
--- /dev/null
+++ b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.md
@@ -0,0 +1,176 @@
+# Solicitud de patente
+
+## Titulo de la invencion
+
+Sistema y procedimiento implementados por ordenador para la identificacion de necesidades terapeuticas mediante escaneo de tarjeta sanitaria individual, contraste con stock farmacutico geolocalizado y generacion de acciones de suministro.
+
+## Solicitante
+
+- Nombre / razon social: Antoni Nuñez Romeu
+- NIF/CIF: 45858029P
+- Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221
+
+## Inventor o inventores
+
+- Nombre y apellidos: Antoni Nuñez Romeu
+- Direccion de contacto: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221
+
+## Resumen
+
+La invencion se refiere a un sistema y un procedimiento implementados por ordenador que permiten, a partir del escaneo de una tarjeta sanitaria individual mediante un terminal movil o dispositivo equivalente, asociar de forma segura un contexto de paciente a una necesidad terapeutica, obtener una referencia de medicamentos relevantes, comparar dicha necesidad con el stock disponible en farmacias geolocalizadas y generar, en caso de falta de disponibilidad, una accion de reserva, aviso, solicitud de pedido o derivacion a una farmacia alternativa. El sistema integra captura de datos, verificacion de identidad, geolocalizacion, consulta de disponibilidad, gestion de stock y generacion de eventos de suministro en una unica cadena tecnica de procesamiento.
+
+## Campo tecnico de la invencion
+
+La invencion se encuadra en los sistemas informaticos aplicados al sector sanitario y farmaceutico, en particular en soluciones de captura de identificadores sanitarios, comparacion automatizada de disponibilidad de medicamentos y asistencia digital a la dispensacion y suministro.
+
+## Antecedentes de la invencion
+
+Las soluciones actuales de busqueda de medicamentos y farmacias permiten localizar productos y mostrar stock aproximado, pero normalmente operan a partir de una busqueda manual por nombre de medicamento o principio activo. Tambien existen sistemas de geolocalizacion y de gestion de inventario, pero suelen estar desacoplados del contexto sanitario del usuario y no integran, en una unica cadena tecnica, la identificacion mediante tarjeta sanitaria individual, la inferencia de necesidades terapeuticas y la comparacion en tiempo real con disponibilidad farmaceutica local.
+
+Ademas, cuando no existe stock en la farmacia mas proxima, el usuario debe iniciar manualmente nuevos procesos de busqueda o desplazamiento, sin que el sistema proponga de forma automatizada acciones tecnicas de reserva, pedido o derivacion basadas en la disponibilidad real.
+
+## Problema tecnico a resolver
+
+La invencion resuelve el problema tecnico de reducir el tiempo y la friccion entre la identificacion de una necesidad terapeutica y la localizacion de una farmacia que disponga del medicamento adecuado, integrando:
+
+- lectura segura de identificadores sanitarios,
+- obtencion de referencias de medicamento asociadas,
+- comparacion automatizada con inventarios de farmacias,
+- priorizacion por proximidad y disponibilidad,
+- generacion de acciones tecnicas de suministro cuando no exista stock inmediato.
+
+## Resumen de la invencion
+
+La invencion propone un sistema y procedimiento implementados por ordenador que operan sobre un terminal movil o dispositivo de lectura. El sistema captura la informacion de una tarjeta sanitaria individual mediante escaneo, valida la informacion mediante un modulo de verificacion, asocia el resultado al perfil del usuario autenticado y obtiene una lista de medicamentos o necesidades terapeuticas relevantes. Posteriormente, un motor de contraste consulta un repositorio de stock de farmacias geolocalizadas y determina la coincidencia entre la necesidad detectada y la disponibilidad real en cada establecimiento. Si existe stock, el sistema prioriza las farmacias adecuadas y presenta una ruta de acceso o reserva. Si no existe stock, el sistema genera automaticamente una accion de aviso, pedido, reserva o derivacion, conservando trazabilidad tecnica del evento. La invencion no se limita a una busqueda manual, sino que integra captura, validacion, georreferenciacion, consulta de stock y respuesta automatica en una unica arquitectura tecnica.
+
+## Breve descripcion de los dibujos
+
+**Figura 1.** Diagrama de bloques general del sistema.
+
+**Figura 2.** Flujo de captura y validacion del escaneo de la TSI.
+
+**Figura 3.** Flujo de contraste entre necesidad terapeutica y stock de farmacias.
+
+**Figura 4.** Flujo de accion cuando no existe stock disponible.
+
+## Descripcion detallada de la invencion
+
+### 1. Arquitectura general
+
+El sistema comprende al menos los siguientes modulos:
+
+1. Un modulo de captura de imagen o lectura optica para escanear la tarjeta sanitaria individual.
+2. Un modulo de extraccion de datos para identificar los campos relevantes de la tarjeta.
+3. Un modulo de verificacion de identidad y autorizacion, vinculado al usuario autenticado.
+4. Un modulo de obtencion de necesidades terapeuticas o medicamentos asociados.
+5. Un modulo de geolocalizacion para obtener la posicion del usuario o una posicion de referencia.
+6. Un modulo de consulta de inventario para recuperar stock, precio y horario de farmacias.
+7. Un modulo de contraste y priorizacion para ordenar farmacias segun disponibilidad y cercania.
+8. Un modulo de generacion de acciones para crear reserva, aviso, pedido o derivacion.
+9. Un modulo de trazabilidad y auditoria.
+
+### 2. Funcionamiento
+
+En una realizacion preferida, el usuario abre la aplicacion y solicita el escaneo de su tarjeta sanitaria individual. El terminal captura la imagen o el codigo de la tarjeta y el modulo de extraccion identifica los datos tecnicos necesarios para enlazar el contexto sanitario del usuario con un conjunto de medicamentos o referencias de tratamiento.
+
+El sistema valida que la operacion se ejecuta sobre un usuario autenticado y autorizado. A continuacion, el motor de contraste consulta el inventario de farmacias cercanas, recuperando para cada farmacia al menos su ubicacion, horario, stock y, opcionalmente, precio.
+
+El modulo de priorizacion calcula una orden de resultados en base a criterios tecnicos tales como:
+
+- existencia de stock,
+- nivel de stock,
+- distancia geografica,
+- horario de apertura,
+- capacidad de reserva o solicitud de pedido.
+
+Cuando existe disponibilidad, el sistema muestra una lista priorizada de farmacias y puede iniciar una reserva o una indicacion de recogida. Cuando no existe disponibilidad, el sistema no se limita a informar de la falta de stock, sino que genera una accion tecnica adicional, por ejemplo:
+
+- alerta a la farmacia seleccionada,
+- solicitud de pedido a distribucion o proveedor,
+- derivacion automatica a otra farmacia con stock,
+- registro de una lista de espera o interes de suministro.
+
+### 3. Tratamiento de datos y seguridad
+
+La invencion prevé que la informacion derivada del escaneo de la TSI se trate con medidas de minimizacion de datos, control de acceso, cifrado en transito y registro de eventos. El sistema no expone innecesariamente los datos de la tarjeta sanitaria y solo conserva los elementos imprescindibles para la operacion descrita.
+
+### 4. Integracion con la plataforma FarmaFinder
+
+En una implementacion concreta, el sistema puede integrarse con una plataforma que ya disponga de:
+
+- catalogo de farmacias,
+- geolocalizacion,
+- stock por medicamento,
+- autenticacion de usuario,
+- notificaciones push,
+- historico de acciones y preferencias.
+
+La integracion permite que el resultado del escaneo de la TSI no se limite a una consulta pasiva, sino que se convierta en un disparador de decisiones tecnicas sobre disponibilidad y suministro.
+
+## Ejemplo de realizacion
+
+1. El usuario inicia sesion en la aplicacion.
+2. El usuario escanea su TSI con la camara del terminal.
+3. El sistema extrae el identificador necesario y lo vincula al perfil autorizado.
+4. El motor terapeutico asocia una necesidad de medicamento o tratamiento.
+5. El sistema consulta farmacias cercanas con stock del medicamento.
+6. Si hay stock, ordena las farmacias por proximidad y disponibilidad.
+7. Si no hay stock, genera una reserva, una alerta o una solicitud de pedido.
+
+## Reivindicaciones
+
+### Reivindicacion 1
+
+Sistema implementado por ordenador para identificar una necesidad terapeutica a partir del escaneo de una tarjeta sanitaria individual, caracterizado porque comprende:
+
+- medios de captura para obtener datos de la tarjeta sanitaria individual;
+- medios de verificacion para asociar dichos datos a un usuario autenticado;
+- medios de obtencion de una referencia de medicamento o necesidad terapeutica;
+- medios de consulta de inventario para recuperar stock de farmacias geolocalizadas;
+- medios de contraste para comparar la referencia de medicamento o necesidad terapeutica con el stock disponible; y
+- medios de generacion de acciones para producir una reserva, aviso, pedido o derivacion cuando el stock disponible sea insuficiente.
+
+### Reivindicacion 2
+
+Sistema segun la reivindicacion 1, en el que los medios de consulta de inventario ordenan las farmacias segun una combinacion de stock disponible, proximidad geografica y horario de apertura.
+
+### Reivindicacion 3
+
+Sistema segun cualquiera de las reivindicaciones anteriores, en el que los datos de la tarjeta sanitaria individual son tratados mediante un modulo de minimizacion y cifrado para limitar su almacenamiento a los campos tecnicamente necesarios.
+
+### Reivindicacion 4
+
+Procedimiento implementado por ordenador para asistir en la localizacion y suministro de medicamentos, caracterizado porque comprende:
+
+1. escanear una tarjeta sanitaria individual;
+2. verificar la autorizacion del usuario;
+3. derivar una necesidad terapeutica o referencia de medicamento;
+4. consultar stock de farmacias geolocalizadas;
+5. comparar la necesidad con el stock disponible; y
+6. generar una accion tecnica de reserva, aviso, pedido o derivacion cuando no exista disponibilidad suficiente.
+
+### Reivindicacion 5
+
+Dispositivo movil, terminal o sistema de lectura que comprende una camara o lector optico y que esta configurado para ejecutar el sistema de cualquiera de las reivindicaciones anteriores.
+
+## Aplicacion industrial
+
+La invencion es susceptible de aplicacion industrial en plataformas de asistencia farmaceutica, sistemas de gestion de inventario, servicios de reserva o pedido de medicamentos y terminales de consulta sanitaria.
+
+## Notas para presentacion en OEPM
+
+- La solicitud debe presentarse como una unica invencion o un unico concepto inventivo general.
+- La descripcion, reivindicaciones y dibujos deben ser coherentes entre si.
+- La proteccion en patente debe apoyarse en un efecto tecnico concreto y no en una mera regla comercial o metodo abstracto.
+- Esta redaccion evita formular una reivindicacion independiente de "programa de ordenador como tal" y se centra en un sistema y un procedimiento implementados por ordenador con interaccion tecnica sobre captura, contraste de inventario y generacion de acciones.
+- Las figuras deben presentarse como laminas separadas si se aportan al expediente.
+- Conviene incluir firma del solicitante y fecha de presentacion en el juego documental final.
+- Antes de presentar la solicitud conviene una busqueda de anterioridades y una revision por agente de propiedad industrial.
+
+## Firma
+
+En Terrassa, a 22 de junio de 2026.
+
+Fdo.: Antoni Nuñez Romeu
+
+DNI/NIF: 45858029P
diff --git a/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.pdf b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.pdf
new file mode 100644
index 0000000..9f67012
--- /dev/null
+++ b/Patentes/SOLICITUD_PATENTE_OEPM_FARMAFINDER.pdf
@@ -0,0 +1,290 @@
+%PDF-1.4
+1 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >>
+endobj
+2 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Bold /Encoding /WinAnsiEncoding >>
+endobj
+3 0 obj
+<< /Type /Font /Subtype /Type1 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >>
+endobj
+4 0 obj
+<< /Length 1104 >>
+stream
+BT /F2 18 Tf 141 783.89 Td (SOLICITUD DE PATENTE) Tj ET
+BT /F1 12 Tf 111 754.85 Td (Oficina Espaola de Patentes y Marcas \(OEPM\)) Tj ET
+BT /F2 12 Tf 176 725.49 Td (Ttulo de la invencin:) Tj ET
+BT /F1 12 Tf 66 710.13 Td (Sistema y procedimiento implementados por ordenador para la identificacin de) Tj ET
+BT /F1 12 Tf 66 694.77 Td (necesidades teraputicas mediante escaneo de tarjeta sanitaria individual,) Tj ET
+BT /F1 12 Tf 66 679.41 Td (contraste con stock farmacutico geolocalizado y generacin de acciones de) Tj ET
+BT /F1 12 Tf 66 664.05 Td (suministro.) Tj ET
+0.8 w 56 580.6899999999999 483.28 68 re S
+BT /F1 11 Tf 66 636.6899999999999 Td (Solicitante: Antoni Nuez Romeu) Tj ET
+BT /F1 11 Tf 66 622.6099999999999 Td (NIF/CIF: 45858029P) Tj ET
+BT /F1 11 Tf 66 608.5299999999999 Td (Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221) Tj ET
+BT /F1 11 Tf 66 594.4499999999998 Td (Inventor o inventores: Antoni Nuez Romeu) Tj ET
+BT /F3 10 Tf 124 568.3699999999998 Td (Memoria descriptiva, reivindicaciones, resumen y referencia a dibujos) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 1) Tj ET
+endstream
+endobj
+5 0 obj
+<< /Length 4950 >>
+stream
+BT /F2 13 Tf 56 781.89 Td (1. Campo tcnico de la invencin) Tj ET
+0.2 w 56 761.25 m 539.28 761.25 l S
+BT /F1 11.5 Tf 56 751.25 Td (La invencin se encuadra en los sistemas informticos aplicados al sector sanitario) Tj ET
+BT /F1 11.5 Tf 56 736.53 Td (y farmacutico, en particular en soluciones de captura de identificadores) Tj ET
+BT /F1 11.5 Tf 56 721.81 Td (sanitarios, comparacin automatizada de disponibilidad de medicamentos y asistencia) Tj ET
+BT /F1 11.5 Tf 56 707.0899999999999 Td (digital a la dispensacin y suministro.) Tj ET
+BT /F2 13 Tf 56 688.3699999999999 Td (2. Antecedentes de la invencin) Tj ET
+0.2 w 56 667.7299999999999 m 539.28 667.7299999999999 l S
+BT /F1 11.5 Tf 56 657.7299999999999 Td (Las soluciones actuales de bsqueda de medicamentos y farmacias permiten localizar) Tj ET
+BT /F1 11.5 Tf 56 643.0099999999999 Td (productos y mostrar stock aproximado, pero normalmente operan a partir de una) Tj ET
+BT /F1 11.5 Tf 56 628.2899999999998 Td (bsqueda manual por nombre de medicamento o principio activo. Tambin existen) Tj ET
+BT /F1 11.5 Tf 56 613.5699999999998 Td (sistemas de geolocalizacin y de gestin de inventario, pero suelen estar) Tj ET
+BT /F1 11.5 Tf 56 598.8499999999998 Td (desacoplados del contexto sanitario del usuario y no integran, en una nica cadena) Tj ET
+BT /F1 11.5 Tf 56 584.1299999999998 Td (tcnica, la identificacin mediante tarjeta sanitaria individual, la inferencia de) Tj ET
+BT /F1 11.5 Tf 56 569.4099999999997 Td (necesidades teraputicas y la comparacin en tiempo real con disponibilidad) Tj ET
+BT /F1 11.5 Tf 56 554.6899999999997 Td (farmacutica local.) Tj ET
+BT /F1 11.5 Tf 56 537.9699999999997 Td (Adems, cuando no existe stock en la farmacia ms prxima, el usuario debe iniciar) Tj ET
+BT /F1 11.5 Tf 56 523.2499999999997 Td (manualmente nuevos procesos de bsqueda o desplazamiento, sin que el sistema) Tj ET
+BT /F1 11.5 Tf 56 508.52999999999963 Td (proponga de forma automatizada acciones tcnicas de reserva, pedido o derivacin) Tj ET
+BT /F1 11.5 Tf 56 493.8099999999996 Td (basadas en la disponibilidad real.) Tj ET
+BT /F2 13 Tf 56 475.0899999999996 Td (3. Problema tcnico a resolver) Tj ET
+0.2 w 56 454.4499999999996 m 539.28 454.4499999999996 l S
+BT /F1 11.5 Tf 56 444.4499999999996 Td (La invencin resuelve el problema tcnico de reducir el tiempo y la friccin entre) Tj ET
+BT /F1 11.5 Tf 56 429.72999999999956 Td (la identificacin de una necesidad teraputica y la localizacin de una farmacia que) Tj ET
+BT /F1 11.5 Tf 56 415.00999999999954 Td (disponga del medicamento adecuado, integrando:) Tj ET
+BT /F1 11.2 Tf 64 398.2899999999995 Td (" lectura segura de identificadores sanitarios,) Tj ET
+BT /F1 11.2 Tf 64 383.9539999999995 Td (" obtencin de referencias de medicamento asociadas,) Tj ET
+BT /F1 11.2 Tf 64 369.6179999999995 Td (" comparacin automatizada con inventarios de farmacias,) Tj ET
+BT /F1 11.2 Tf 64 355.28199999999947 Td (" priorizacin por proximidad y disponibilidad,) Tj ET
+BT /F1 11.2 Tf 64 340.94599999999946 Td (" generacin de acciones tcnicas de suministro cuando no exista stock inmediato.) Tj ET
+BT /F2 13 Tf 56 324.60999999999945 Td (4. Resumen de la invencin) Tj ET
+0.2 w 56 303.96999999999946 m 539.28 303.96999999999946 l S
+BT /F1 11.5 Tf 56 293.96999999999946 Td (La invencin propone un sistema y procedimiento implementados por ordenador que) Tj ET
+BT /F1 11.5 Tf 56 279.24999999999943 Td (operan sobre un terminal mvil o dispositivo de lectura. El sistema captura la) Tj ET
+BT /F1 11.5 Tf 56 264.5299999999994 Td (informacin de una tarjeta sanitaria individual mediante escaneo, valida la) Tj ET
+BT /F1 11.5 Tf 56 249.8099999999994 Td (informacin mediante un mdulo de verificacin, asocia el resultado al perfil del) Tj ET
+BT /F1 11.5 Tf 56 235.0899999999994 Td (usuario autenticado y obtiene una lista de medicamentos o necesidades teraputicas) Tj ET
+BT /F1 11.5 Tf 56 220.3699999999994 Td (relevantes. Posteriormente, un motor de contraste consulta un repositorio de stock) Tj ET
+BT /F1 11.5 Tf 56 205.6499999999994 Td (de farmacias geolocalizadas y determina la coincidencia entre la necesidad detectada) Tj ET
+BT /F1 11.5 Tf 56 190.9299999999994 Td (y la disponibilidad real en cada establecimiento. Si existe stock, el sistema) Tj ET
+BT /F1 11.5 Tf 56 176.2099999999994 Td (prioriza las farmacias adecuadas y presenta una ruta de acceso o reserva. Si no) Tj ET
+BT /F1 11.5 Tf 56 161.4899999999994 Td (existe stock, el sistema genera automticamente una accin de aviso, pedido, reserva) Tj ET
+BT /F1 11.5 Tf 56 146.7699999999994 Td (o derivacin, conservando trazabilidad tcnica del evento. La invencin no se limita) Tj ET
+BT /F1 11.5 Tf 56 132.04999999999941 Td (a una bsqueda manual, sino que integra captura, validacin, georreferenciacin,) Tj ET
+BT /F1 11.5 Tf 56 117.32999999999942 Td (consulta de stock y respuesta automtica en una nica arquitectura tcnica.) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 2) Tj ET
+endstream
+endobj
+6 0 obj
+<< /Length 3436 >>
+stream
+BT /F2 13 Tf 56 781.89 Td (5. Breve descripcin de los dibujos) Tj ET
+0.2 w 56 761.25 m 539.28 761.25 l S
+BT /F1 11.5 Tf 56 751.25 Td (Figura 1. Diagrama de bloques general del sistema.) Tj ET
+BT /F1 11.5 Tf 56 734.53 Td (Figura 2. Flujo de captura y validacin del escaneo de la TSI.) Tj ET
+BT /F1 11.5 Tf 56 717.81 Td (Figura 3. Flujo de contraste entre necesidad teraputica y stock de farmacias.) Tj ET
+BT /F1 11.5 Tf 56 701.0899999999999 Td (Figura 4. Flujo de accin cuando no existe stock disponible.) Tj ET
+BT /F2 13 Tf 56 682.3699999999999 Td (6. Descripcin detallada de la invencin) Tj ET
+0.2 w 56 661.7299999999999 m 539.28 661.7299999999999 l S
+BT /F2 11.5 Tf 56 651.7299999999999 Td (6.1 Arquitectura general) Tj ET
+BT /F1 11.5 Tf 56 637.0099999999999 Td (El sistema comprende al menos los siguientes mdulos:) Tj ET
+BT /F1 11.2 Tf 64 620.2899999999998 Td (1. un mdulo de captura de imagen o lectura ptica para escanear la tarjeta sanitaria) Tj ET
+BT /F1 11.2 Tf 64 605.9539999999998 Td ( individual;) Tj ET
+BT /F1 11.2 Tf 64 591.6179999999998 Td (2. un mdulo de extraccin de datos para identificar los campos relevantes de la tarjeta;) Tj ET
+BT /F1 11.2 Tf 64 577.2819999999998 Td (3. un mdulo de verificacin de identidad y autorizacin, vinculado al usuario) Tj ET
+BT /F1 11.2 Tf 64 562.9459999999998 Td ( autenticado;) Tj ET
+BT /F1 11.2 Tf 64 548.6099999999998 Td (4. un mdulo de obtencin de necesidades teraputicas o medicamentos asociados;) Tj ET
+BT /F1 11.2 Tf 64 534.2739999999998 Td (5. un mdulo de geolocalizacin para obtener la posicin del usuario o una posicin de) Tj ET
+BT /F1 11.2 Tf 64 519.9379999999998 Td ( referencia;) Tj ET
+BT /F1 11.2 Tf 64 505.60199999999975 Td (6. un mdulo de consulta de inventario para recuperar stock, precio y horario de) Tj ET
+BT /F1 11.2 Tf 64 491.26599999999974 Td ( farmacias;) Tj ET
+BT /F1 11.2 Tf 64 476.9299999999997 Td (7. un mdulo de contraste y priorizacin para ordenar farmacias segn disponibilidad y) Tj ET
+BT /F1 11.2 Tf 64 462.5939999999997 Td ( cercana;) Tj ET
+BT /F1 11.2 Tf 64 448.2579999999997 Td (8. un mdulo de generacin de acciones para crear reserva, aviso, pedido o derivacin;) Tj ET
+BT /F1 11.2 Tf 64 433.9219999999997 Td (9. un mdulo de trazabilidad y auditora.) Tj ET
+BT /F2 11.5 Tf 56 419.5859999999997 Td (6.2 Funcionamiento) Tj ET
+BT /F1 11.5 Tf 56 404.86599999999964 Td (En una realizacin preferida, el usuario abre la aplicacin y solicita el escaneo de) Tj ET
+BT /F1 11.5 Tf 56 390.1459999999996 Td (su tarjeta sanitaria individual. El terminal captura la imagen o el cdigo de la) Tj ET
+BT /F1 11.5 Tf 56 375.4259999999996 Td (tarjeta y el mdulo de extraccin identifica los datos tcnicos necesarios para) Tj ET
+BT /F1 11.5 Tf 56 360.70599999999956 Td (enlazar el contexto sanitario del usuario con un conjunto de medicamentos o) Tj ET
+BT /F1 11.5 Tf 56 345.98599999999954 Td (referencias de tratamiento.) Tj ET
+BT /F1 11.5 Tf 56 329.2659999999995 Td (El sistema valida que la operacin se ejecuta sobre un usuario autenticado y) Tj ET
+BT /F1 11.5 Tf 56 314.5459999999995 Td (autorizado. A continuacin, el motor de contraste consulta el inventario de) Tj ET
+BT /F1 11.5 Tf 56 299.82599999999945 Td (farmacias cercanas, recuperando para cada farmacia al menos su ubicacin, horario,) Tj ET
+BT /F1 11.5 Tf 56 285.1059999999994 Td (stock y, opcionalmente, precio.) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 3) Tj ET
+endstream
+endobj
+7 0 obj
+<< /Length 3271 >>
+stream
+BT /F2 11.5 Tf 56 783.89 Td (6.2 Funcionamiento \(continuacin\)) Tj ET
+BT /F1 11.5 Tf 56 769.17 Td (El mdulo de priorizacin calcula una orden de resultados en base a criterios) Tj ET
+BT /F1 11.5 Tf 56 754.4499999999999 Td (tcnicos tales como existencia de stock, nivel de stock, distancia geogrfica,) Tj ET
+BT /F1 11.5 Tf 56 739.7299999999999 Td (horario de apertura y capacidad de reserva o solicitud de pedido.) Tj ET
+BT /F1 11.5 Tf 56 723.0099999999999 Td (Cuando existe disponibilidad, el sistema muestra una lista priorizada de farmacias y) Tj ET
+BT /F1 11.5 Tf 56 708.2899999999998 Td (puede iniciar una reserva o una indicacin de recogida. Cuando no existe) Tj ET
+BT /F1 11.5 Tf 56 693.5699999999998 Td (disponibilidad, el sistema no se limita a informar de la falta de stock, sino que) Tj ET
+BT /F1 11.5 Tf 56 678.8499999999998 Td (genera una accin tcnica adicional, por ejemplo alerta a la farmacia seleccionada,) Tj ET
+BT /F1 11.5 Tf 56 664.1299999999998 Td (solicitud de pedido a distribucin o proveedor, derivacin automtica a otra) Tj ET
+BT /F1 11.5 Tf 56 649.4099999999997 Td (farmacia con stock o registro de una lista de espera o inters de suministro.) Tj ET
+BT /F2 11.5 Tf 56 632.6899999999997 Td (6.3 Tratamiento de datos y seguridad) Tj ET
+BT /F1 11.5 Tf 56 617.9699999999997 Td (La invencin prev que la informacin derivada del escaneo de la TSI se trate con) Tj ET
+BT /F1 11.5 Tf 56 603.2499999999997 Td (medidas de minimizacin de datos, control de acceso, cifrado en trnsito y registro) Tj ET
+BT /F1 11.5 Tf 56 588.5299999999996 Td (de eventos. El sistema no expone innecesariamente los datos de la tarjeta sanitaria) Tj ET
+BT /F1 11.5 Tf 56 573.8099999999996 Td (y solo conserva los elementos imprescindibles para la operacin descrita.) Tj ET
+BT /F2 11.5 Tf 56 557.0899999999996 Td (6.4 Integracin con la plataforma FarmaFinder) Tj ET
+BT /F1 11.5 Tf 56 542.3699999999995 Td (En una implementacin concreta, el sistema puede integrarse con una plataforma que) Tj ET
+BT /F1 11.5 Tf 56 527.6499999999995 Td (ya disponga de catlogo de farmacias, geolocalizacin, stock por medicamento,) Tj ET
+BT /F1 11.5 Tf 56 512.9299999999995 Td (autenticacin de usuario, notificaciones push e histrico de acciones y) Tj ET
+BT /F1 11.5 Tf 56 498.20999999999947 Td (preferencias.) Tj ET
+BT /F1 11.5 Tf 56 481.48999999999944 Td (La integracin permite que el resultado del escaneo de la TSI no se limite a una) Tj ET
+BT /F1 11.5 Tf 56 466.7699999999994 Td (consulta pasiva, sino que se convierta en un disparador de decisiones tcnicas sobre) Tj ET
+BT /F1 11.5 Tf 56 452.0499999999994 Td (disponibilidad y suministro.) Tj ET
+BT /F2 13 Tf 56 433.32999999999936 Td (7. Ejemplo de realizacin) Tj ET
+0.2 w 56 412.6899999999994 m 539.28 412.6899999999994 l S
+BT /F1 11.2 Tf 64 402.6899999999994 Td (1. El usuario inicia sesin en la aplicacin.) Tj ET
+BT /F1 11.2 Tf 64 388.35399999999936 Td (2. El usuario escanea su TSI con la cmara del terminal.) Tj ET
+BT /F1 11.2 Tf 64 374.01799999999935 Td (3. El sistema extrae el identificador necesario y lo vincula al perfil autorizado.) Tj ET
+BT /F1 11.2 Tf 64 359.68199999999933 Td (4. El motor teraputico asocia una necesidad de medicamento o tratamiento.) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 4) Tj ET
+endstream
+endobj
+8 0 obj
+<< /Length 3689 >>
+stream
+BT /F2 13 Tf 56 781.89 Td (7. Ejemplo de realizacin \(continuacin\)) Tj ET
+0.2 w 56 761.25 m 539.28 761.25 l S
+BT /F1 11.2 Tf 64 751.25 Td (1. El sistema consulta farmacias cercanas con stock del medicamento.) Tj ET
+BT /F1 11.2 Tf 64 736.914 Td (2. Si hay stock, ordena las farmacias por proximidad y disponibilidad.) Tj ET
+BT /F1 11.2 Tf 64 722.578 Td (3. Si no hay stock, genera una reserva, una alerta o una solicitud de pedido.) Tj ET
+BT /F2 13 Tf 56 706.242 Td (8. Reivindicaciones) Tj ET
+0.2 w 56 685.602 m 539.28 685.602 l S
+BT /F1 11.2 Tf 56 675.602 Td (Reivindicacin 1. Sistema implementado por ordenador para identificar una necesidad) Tj ET
+BT /F1 11.2 Tf 56 661.266 Td (teraputica a partir del escaneo de una tarjeta sanitaria individual, caracterizado) Tj ET
+BT /F1 11.2 Tf 56 646.93 Td (porque comprende medios de captura para obtener datos de la tarjeta sanitaria) Tj ET
+BT /F1 11.2 Tf 56 632.5939999999999 Td (individual; medios de verificacin para asociar dichos datos a un usuario autenticado;) Tj ET
+BT /F1 11.2 Tf 56 618.2579999999999 Td (medios de obtencin de una referencia de medicamento o necesidad teraputica; medios) Tj ET
+BT /F1 11.2 Tf 56 603.9219999999999 Td (de consulta de inventario para recuperar stock de farmacias geolocalizadas; medios de) Tj ET
+BT /F1 11.2 Tf 56 589.5859999999999 Td (contraste para comparar la referencia de medicamento o necesidad teraputica con el) Tj ET
+BT /F1 11.2 Tf 56 575.2499999999999 Td (stock disponible; y medios de generacin de acciones para producir una reserva, aviso,) Tj ET
+BT /F1 11.2 Tf 56 560.9139999999999 Td (pedido o derivacin cuando el stock disponible sea insuficiente.) Tj ET
+BT /F1 11.2 Tf 56 544.5779999999999 Td (Reivindicacin 2. Sistema segn la reivindicacin 1, en el que los medios de consulta) Tj ET
+BT /F1 11.2 Tf 56 530.2419999999998 Td (de inventario ordenan las farmacias segn una combinacin de stock disponible,) Tj ET
+BT /F1 11.2 Tf 56 515.9059999999998 Td (proximidad geogrfica y horario de apertura.) Tj ET
+BT /F1 11.2 Tf 56 499.5699999999998 Td (Reivindicacin 3. Sistema segn cualquiera de las reivindicaciones anteriores, en el) Tj ET
+BT /F1 11.2 Tf 56 485.2339999999998 Td (que los datos de la tarjeta sanitaria individual son tratados mediante un mdulo de) Tj ET
+BT /F1 11.2 Tf 56 470.8979999999998 Td (minimizacin y cifrado para limitar su almacenamiento a los campos tcnicamente) Tj ET
+BT /F1 11.2 Tf 56 456.5619999999998 Td (necesarios.) Tj ET
+BT /F1 11.2 Tf 56 440.2259999999998 Td (Reivindicacin 4. Procedimiento implementado por ordenador para asistir en la) Tj ET
+BT /F1 11.2 Tf 56 425.88999999999976 Td (localizacin y suministro de medicamentos, caracterizado porque comprende escanear una) Tj ET
+BT /F1 11.2 Tf 56 411.55399999999975 Td (tarjeta sanitaria individual; verificar la autorizacin del usuario; derivar una) Tj ET
+BT /F1 11.2 Tf 56 397.21799999999973 Td (necesidad teraputica o referencia de medicamento; consultar stock de farmacias) Tj ET
+BT /F1 11.2 Tf 56 382.8819999999997 Td (geolocalizadas; comparar la necesidad con el stock disponible; y generar una accin) Tj ET
+BT /F1 11.2 Tf 56 368.5459999999997 Td (tcnica de reserva, aviso, pedido o derivacin cuando no exista disponibilidad) Tj ET
+BT /F1 11.2 Tf 56 354.2099999999997 Td (suficiente.) Tj ET
+BT /F1 11.2 Tf 56 337.8739999999997 Td (Reivindicacin 5. Dispositivo mvil, terminal o sistema de lectura que comprende una) Tj ET
+BT /F1 11.2 Tf 56 323.53799999999967 Td (cmara o lector ptico y que est configurado para ejecutar el sistema de cualquiera) Tj ET
+BT /F1 11.2 Tf 56 309.20199999999966 Td (de las reivindicaciones anteriores.) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 5) Tj ET
+endstream
+endobj
+9 0 obj
+<< /Length 4216 >>
+stream
+BT /F2 13 Tf 56 781.89 Td (9. Aplicacin industrial) Tj ET
+0.2 w 56 761.25 m 539.28 761.25 l S
+BT /F1 11.5 Tf 56 751.25 Td (La invencin es susceptible de aplicacin industrial en plataformas de asistencia) Tj ET
+BT /F1 11.5 Tf 56 736.53 Td (farmacutica, sistemas de gestin de inventario, servicios de reserva o pedido de) Tj ET
+BT /F1 11.5 Tf 56 721.81 Td (medicamentos y terminales de consulta sanitaria.) Tj ET
+BT /F2 13 Tf 56 703.0899999999999 Td (10. Resumen) Tj ET
+0.2 w 56 682.4499999999999 m 539.28 682.4499999999999 l S
+BT /F1 11.5 Tf 56 672.4499999999999 Td (La presente invencin se refiere a un sistema y procedimiento implementados por) Tj ET
+BT /F1 11.5 Tf 56 657.7299999999999 Td (ordenador que permiten, a partir del escaneo de una tarjeta sanitaria individual) Tj ET
+BT /F1 11.5 Tf 56 643.0099999999999 Td (mediante un terminal mvil o dispositivo equivalente, asociar de forma segura un) Tj ET
+BT /F1 11.5 Tf 56 628.2899999999998 Td (contexto de paciente a una necesidad teraputica, obtener una referencia de) Tj ET
+BT /F1 11.5 Tf 56 613.5699999999998 Td (medicamentos relevantes, comparar dicha necesidad con el stock disponible en) Tj ET
+BT /F1 11.5 Tf 56 598.8499999999998 Td (farmacias geolocalizadas y generar, en caso de falta de disponibilidad, una accin) Tj ET
+BT /F1 11.5 Tf 56 584.1299999999998 Td (de reserva, aviso, solicitud de pedido o derivacin a una farmacia alternativa. El) Tj ET
+BT /F1 11.5 Tf 56 569.4099999999997 Td (sistema integra captura de datos, verificacin de identidad, geolocalizacin,) Tj ET
+BT /F1 11.5 Tf 56 554.6899999999997 Td (consulta de disponibilidad, gestin de stock y generacin de eventos de suministro) Tj ET
+BT /F1 11.5 Tf 56 539.9699999999997 Td (en una nica cadena tcnica de procesamiento.) Tj ET
+BT /F2 13 Tf 56 521.2499999999997 Td (11. Anexo de dibujos) Tj ET
+0.2 w 56 500.6099999999997 m 539.28 500.6099999999997 l S
+BT /F1 11.5 Tf 56 490.6099999999997 Td (Las figuras indicadas en la presente memoria tienen carcter esquemtico y se) Tj ET
+BT /F1 11.5 Tf 56 475.88999999999965 Td (incorporan a efectos ilustrativos de la arquitectura, del flujo de captura, del) Tj ET
+BT /F1 11.5 Tf 56 461.1699999999996 Td (contraste de stock y de la generacin de acciones. En una presentacin definitiva,) Tj ET
+BT /F1 11.5 Tf 56 446.4499999999996 Td (dichas figuras podrn acompaarse como lminas separadas numeradas de forma) Tj ET
+BT /F1 11.5 Tf 56 431.72999999999956 Td (consecutiva.) Tj ET
+BT /F2 13 Tf 56 413.00999999999954 Td (12. Firma del solicitante) Tj ET
+0.2 w 56 392.36999999999955 m 539.28 392.36999999999955 l S
+BT /F1 11.5 Tf 56 382.36999999999955 Td (En Terrassa, a 22 de junio de 2026.) Tj ET
+BT /F1 11.5 Tf 56 365.6499999999995 Td (Fdo.: Antoni Nuez Romeu) Tj ET
+BT /F1 11.5 Tf 56 348.9299999999995 Td (DNI/NIF: 45858029P) Tj ET
+BT /F2 13 Tf 56 330.20999999999947 Td (13. Notas para presentacin en OEPM) Tj ET
+0.2 w 56 309.5699999999995 m 539.28 309.5699999999995 l S
+BT /F1 11.2 Tf 64 299.5699999999995 Td (" La solicitud debe presentarse como una nica invencin o un nico concepto inventivo) Tj ET
+BT /F1 11.2 Tf 64 285.23399999999947 Td ( general.) Tj ET
+BT /F1 11.2 Tf 64 270.89799999999946 Td (" La descripcin, reivindicaciones y dibujos deben ser coherentes entre s.) Tj ET
+BT /F1 11.2 Tf 64 256.56199999999944 Td (" La proteccin en patente debe apoyarse en un efecto tcnico concreto y no en una mera) Tj ET
+BT /F1 11.2 Tf 64 242.22599999999943 Td ( regla comercial o mtodo abstracto.) Tj ET
+BT /F1 11.2 Tf 64 227.88999999999942 Td (" Esta redaccin evita formular una reivindicacin independiente de "programa de) Tj ET
+BT /F1 11.2 Tf 64 213.5539999999994 Td ( ordenador como tal" y se centra en un sistema y un procedimiento implementados por) Tj ET
+BT /F1 11.2 Tf 64 199.2179999999994 Td ( ordenador con interaccin tcnica sobre captura, contraste de inventario y generacin) Tj ET
+BT /F1 11.2 Tf 64 184.88199999999938 Td ( de acciones.) Tj ET
+BT /F1 11.2 Tf 64 170.54599999999937 Td (" Antes de presentar la solicitud conviene una bsqueda de anterioridades y una revisin) Tj ET
+BT /F1 11.2 Tf 64 156.20999999999935 Td ( por agente de propiedad industrial.) Tj ET
+BT /F1 9 Tf 495.28 24 Td (Pagina 6) Tj ET
+endstream
+endobj
+10 0 obj
+<< /Type /Pages /Kids [11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R] /Count 6 >>
+endobj
+11 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 4 0 R >>
+endobj
+12 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 5 0 R >>
+endobj
+13 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 6 0 R >>
+endobj
+14 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 7 0 R >>
+endobj
+15 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 8 0 R >>
+endobj
+16 0 obj
+<< /Type /Page /Parent 10 0 R /MediaBox [0 0 595.28 841.89] /Resources << /Font << /F1 1 0 R /F2 2 0 R /F3 3 0 R >> >> /Contents 9 0 R >>
+endobj
+17 0 obj
+<< /Type /Catalog /Pages 10 0 R >>
+endobj
+xref
+0 18
+0000000000 65535 f
+0000000009 00000 n
+0000000108 00000 n
+0000000206 00000 n
+0000000306 00000 n
+0000001462 00000 n
+0000006464 00000 n
+0000009952 00000 n
+0000013275 00000 n
+0000017016 00000 n
+0000021284 00000 n
+0000021378 00000 n
+0000021532 00000 n
+0000021686 00000 n
+0000021840 00000 n
+0000021994 00000 n
+0000022148 00000 n
+0000022302 00000 n
+trailer << /Size 18 /Root 17 0 R >>
+startxref
+22353
+%%EOF
diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle
index 8c6bf7c..d17ceef 100644
--- a/android/app/capacitor.build.gradle
+++ b/android/app/capacitor.build.gradle
@@ -2,8 +2,8 @@
android {
compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
+ sourceCompatibility JavaVersion.VERSION_21
+ targetCompatibility JavaVersion.VERSION_21
}
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 3d74400..3649457 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -10,7 +10,7 @@
android:theme="@style/AppTheme">
+
+
diff --git a/android/build.gradle b/android/build.gradle
index 85a5dda..f8f0e43 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -7,8 +7,8 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.2.1'
- classpath 'com.google.gms:google-services:4.4.0'
+ classpath 'com.android.tools.build:gradle:8.13.0'
+ classpath 'com.google.gms:google-services:4.4.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index c747538..5e6c1d0 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
+#Fri Jun 26 12:32:52 CEST 2026
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/android/variables.gradle b/android/variables.gradle
index 8ef305d..e14d745 100644
--- a/android/variables.gradle
+++ b/android/variables.gradle
@@ -1,16 +1,16 @@
ext {
- minSdkVersion = 22
- compileSdkVersion = 34
- targetSdkVersion = 34
- androidxActivityVersion = '1.8.0'
- androidxAppCompatVersion = '1.6.1'
- androidxCoordinatorLayoutVersion = '1.2.0'
- androidxCoreVersion = '1.12.0'
- androidxFragmentVersion = '1.6.2'
- coreSplashScreenVersion = '1.0.1'
- androidxWebkitVersion = '1.9.0'
+ minSdkVersion = 24
+ compileSdkVersion = 36
+ targetSdkVersion = 36
+ androidxActivityVersion = '1.11.0'
+ androidxAppCompatVersion = '1.7.1'
+ androidxCoordinatorLayoutVersion = '1.3.0'
+ androidxCoreVersion = '1.17.0'
+ androidxFragmentVersion = '1.8.9'
+ coreSplashScreenVersion = '1.2.0'
+ androidxWebkitVersion = '1.14.0'
junitVersion = '4.13.2'
- androidxJunitVersion = '1.1.5'
- androidxEspressoCoreVersion = '3.5.1'
- cordovaAndroidVersion = '10.1.1'
-}
\ No newline at end of file
+ androidxJunitVersion = '1.3.0'
+ androidxEspressoCoreVersion = '3.7.0'
+ cordovaAndroidVersion = '14.0.1'
+}
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 7785089..4ad3d35 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,6 +1,7 @@
-FROM node:18-alpine
+FROM node:18-slim
WORKDIR /app
COPY backend/package*.json ./
+RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/*
RUN npm ci --omit=dev
COPY backend/ .
COPY API/ /API/
diff --git a/backend/server.js b/backend/server.js
index aa685ab..34dc883 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -340,6 +340,55 @@ app.get('/api/pharmacies', async (req, res) => {
}
});
+// TSI Card scan: return mock prescriptions for a given CIP
+// In production this would integrate with a real health data source
+app.get('/api/tsi/:cip/prescriptions', async (req, res) => {
+ try {
+ const cip = req.params.cip || '';
+
+ // Deterministic prescription set based on CIP prefix — simulates per-patient data
+ const cipUpper = cip.toUpperCase();
+ let medicineNames;
+ if (cipUpper.startsWith('ALPE')) {
+ medicineNames = ['Paracetamol', 'Omeprazol', 'Ibuprofeno'];
+ } else if (cipUpper.startsWith('MADS')) {
+ medicineNames = ['Amoxicilina', 'Loratadina', 'Ibuprofeno'];
+ } else if (cipUpper.startsWith('VALE')) {
+ medicineNames = ['Atorvastatina', 'Metformina', 'Losartán'];
+ } else {
+ medicineNames = ['Paracetamol', 'Ibuprofeno'];
+ }
+
+ // Build a static prescription list (CIMA API mock)
+ const prescriptions = medicineNames.map((name, idx) => {
+ const dosages = ['500mg', '20mg', '600mg', '500mg', '850mg'];
+ const forms = ['Comprimidos', 'Cápsulas', 'Comprimidos recubiertos', 'Cápsulas', 'Comprimidos'];
+ const actives = {
+ 'Paracetamol': 'Paracetamol',
+ 'Omeprazol': 'Omeprazol',
+ 'Ibuprofeno': 'Ibuprofeno',
+ 'Amoxicilina': 'Amoxicilina',
+ 'Loratadina': 'Loratadina',
+ 'Atorvastatina': 'Atorvastatina',
+ 'Metformina': 'Metformina',
+ 'Losartán': 'Losartán potásico',
+ };
+ return {
+ id: `RX_${cip}_${idx}`,
+ name: name,
+ active_ingredient: actives[name] || name,
+ dosage: dosages[idx % dosages.length],
+ form: forms[idx % forms.length],
+ };
+ });
+
+ res.json(prescriptions);
+ } catch (error) {
+ console.error('Error fetching TSI prescriptions:', error);
+ res.status(500).json({ error: 'Internal server error' });
+ }
+});
+
// ========== AUTHENTICATION MIDDLEWARE ==========
// Middleware to check if user is authenticated
diff --git a/bitrise.yml b/bitrise.yml
new file mode 100644
index 0000000..2b29055
--- /dev/null
+++ b/bitrise.yml
@@ -0,0 +1,198 @@
+---
+format_version: "11"
+default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
+
+project_type: capacitor
+
+app:
+ envs:
+ - BITRISE_PROJECT_PATH: ""
+ - BITRISE_SCHEME: ""
+
+trigger_map:
+ - push_branch: main
+ workflow: deploy
+ - pull_request_source_branch: "*"
+ workflow: test
+ - tag: "*"
+ workflow: deploy
+
+workflows:
+ # ── Shared setup ──────────────────────────────────────────
+ _setup:
+ steps:
+ - activate-ssh-key@4:
+ run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
+ - git-clone@8: {}
+ - nvm@1:
+ inputs:
+ - node_version: "20"
+ - script@1:
+ title: Install dependencies & build frontend
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npm install
+ npm install --prefix frontend
+ npm run build --prefix frontend
+
+ # ── Android test / PR build ──────────────────────────────
+ test:
+ before_run:
+ - _setup
+ steps:
+ - script@1:
+ title: Sync Android native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync android
+ - script@1:
+ title: Install Android SDK components
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
+ "platforms;android-36" \
+ "build-tools;36.0.0" \
+ "platform-tools" || true
+ - android-build@1:
+ title: Build Android APK (debug)
+ inputs:
+ - project_location: android
+ - module: app
+ - variant: debug
+
+ # ── Android deploy ───────────────────────────────────────
+ deploy_android:
+ before_run:
+ - _setup
+ steps:
+ - script@1:
+ title: Sync Android native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync android
+ - script@1:
+ title: Install Android SDK components
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
+ "platforms;android-36" \
+ "build-tools;36.0.0" \
+ "platform-tools" || true
+ - android-build@1:
+ title: Build Android AAB (release)
+ inputs:
+ - project_location: android
+ - module: app
+ - variant: release
+ - deploy-to-bitrise-io@2: {}
+
+ # ── iOS test / PR build ─────────────────────────────────
+ test_ios:
+ before_run:
+ - _setup
+ steps:
+ - script@1:
+ title: Sync iOS native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync ios
+ - cocoapods-install@2:
+ inputs:
+ - podfile_path: ios/App/Podfile
+ - xcode-archive@4:
+ title: Build iOS (simulator)
+ inputs:
+ - project_path: ios/App/App.xcodeproj
+ - scheme: App
+ - configuration: Debug
+ - destination: platform=iOS Simulator,name=iPhone 15,OS=latest
+ - output_tool: xcodebuild
+
+ # ── iOS deploy ───────────────────────────────────────────
+ deploy_ios:
+ before_run:
+ - _setup
+ steps:
+ - script@1:
+ title: Sync iOS native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync ios
+ - cocoapods-install@2:
+ inputs:
+ - podfile_path: ios/App/Podfile
+ - xcode-archive@4:
+ title: Archive iOS (release)
+ inputs:
+ - project_path: ios/App/App.xcodeproj
+ - scheme: App
+ - configuration: Release
+ - destination: generic/platform=iOS
+ - output_tool: xcodebuild
+ - export_method: app-store
+ - deploy-to-bitrise-io@2: {}
+
+ # ── Full deploy (both platforms) ─────────────────────────
+ deploy:
+ before_run:
+ - _setup
+ steps:
+ # Android
+ - script@1:
+ title: Sync Android native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync android
+ - script@1:
+ title: Install Android SDK components
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
+ "platforms;android-36" \
+ "build-tools;36.0.0" \
+ "platform-tools" || true
+ - android-build@1:
+ title: Build Android AAB (release)
+ inputs:
+ - project_location: android
+ - module: app
+ - variant: release
+ # iOS
+ - script@1:
+ title: Sync iOS native project
+ inputs:
+ - content: |
+ #!/bin/bash
+ set -ex
+ npx cap sync ios
+ - cocoapods-install@2:
+ inputs:
+ - podfile_path: ios/App/Podfile
+ - xcode-archive@4:
+ title: Archive iOS (release)
+ inputs:
+ - project_path: ios/App/App.xcodeproj
+ - scheme: App
+ - configuration: Release
+ - destination: generic/platform=iOS
+ - output_tool: xcodebuild
+ - export_method: app-store
+ - deploy-to-bitrise-io@2: {}
diff --git a/dibujos/figura_1.jpg b/dibujos/figura_1.jpg
new file mode 100644
index 0000000..82697b4
Binary files /dev/null and b/dibujos/figura_1.jpg differ
diff --git a/dibujos/figura_2.jpg b/dibujos/figura_2.jpg
new file mode 100644
index 0000000..e47ff51
Binary files /dev/null and b/dibujos/figura_2.jpg differ
diff --git a/dibujos/figura_3.jpg b/dibujos/figura_3.jpg
new file mode 100644
index 0000000..0e5d359
Binary files /dev/null and b/dibujos/figura_3.jpg differ
diff --git a/dibujos/figura_4.jpg b/dibujos/figura_4.jpg
new file mode 100644
index 0000000..a1a1145
Binary files /dev/null and b/dibujos/figura_4.jpg differ
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index bd4bbf6..14d5c2a 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,10 +8,12 @@
"name": "farma-finder-frontend",
"version": "1.0.0",
"dependencies": {
- "@capacitor/app": "^6.0.3",
- "@capacitor/core": "^6.2.1",
- "@capacitor/splash-screen": "^6.0.4",
- "@capacitor/status-bar": "^6.0.3",
+ "@capacitor-mlkit/barcode-scanning": "^8.1.0",
+ "@capacitor/app": "^8.1.0",
+ "@capacitor/core": "^8.4.1",
+ "@capacitor/splash-screen": "^8.0.1",
+ "@capacitor/status-bar": "^8.0.2",
+ "barcode-detector": "^3.2.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@@ -1646,40 +1648,54 @@
"node": ">=6.9.0"
}
},
- "node_modules/@capacitor/app": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-6.0.3.tgz",
- "integrity": "sha512-4gFUCbcVz0N/YYN32OBFerocWXslIv3Nc90gDiRsBkJc0plwK6kIUT6PKa5WtW2kfhteUeCVXQbvArH2fH+0Ug==",
- "license": "MIT",
+ "node_modules/@capacitor-mlkit/barcode-scanning": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@capacitor-mlkit/barcode-scanning/-/barcode-scanning-8.1.0.tgz",
+ "integrity": "sha512-lhOYHZINLOCT0i5YSbSMkouik3zh0BncJouumNTgXCT0/533Z4733jAX9zv+nEd++bE8QHeUl2g0NrewreumnQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/capawesome-team/"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/capawesome"
+ }
+ ],
"peerDependencies": {
- "@capacitor/core": "^6.0.0"
+ "@capacitor/core": ">=8.0.0"
+ }
+ },
+ "node_modules/@capacitor/app": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-8.1.0.tgz",
+ "integrity": "sha512-MlmttTOWHDedr/G4SrhNRxsXMqY+R75S4MM4eIgzsgCzOYhb/MpCkA5Q3nuOCfL1oHm26xjUzqZ5aupbOwdfYg==",
+ "peerDependencies": {
+ "@capacitor/core": ">=8.0.0"
}
},
"node_modules/@capacitor/core": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-6.2.1.tgz",
- "integrity": "sha512-urZwxa7hVE/BnA18oCFAdizXPse6fCKanQyEqpmz6cBJ2vObwMpyJDG5jBeoSsgocS9+Ax+9vb4ducWJn0y2qQ==",
- "license": "MIT",
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.4.1.tgz",
+ "integrity": "sha512-xqhOGLbTAYeOWK+IDUNSjQJAPapQjRHrIcgk9PYp52or9zFTaaMko31uNi16N6W+CRJ8VrRram6fOYILkBG2Hg==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@capacitor/splash-screen": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/@capacitor/splash-screen/-/splash-screen-6.0.4.tgz",
- "integrity": "sha512-uJXR+28cdaie7zIIUBvgkWgHim6Gr1itJym9voIMTmrjXkOaPtejwxYJsdQWPJz9zgGnSbXuC1mNNibLgv3OpQ==",
- "license": "MIT",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@capacitor/splash-screen/-/splash-screen-8.0.1.tgz",
+ "integrity": "sha512-c/ew/Z3eA7z8l06WoRAtzVF16VwYYrExmHmfGq1Cg675pVzaC/yuucB8/1xG1vhEfnW4fZ1KhSf/kzR1RiVYgg==",
"peerDependencies": {
- "@capacitor/core": "^6.0.0"
+ "@capacitor/core": ">=8.0.0"
}
},
"node_modules/@capacitor/status-bar": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-6.0.3.tgz",
- "integrity": "sha512-nFlgSmtx6Zwaw0tEvZgQsWHBeOfWWB/AvEoCApopLT4mHkBVoSrwkLvy2PjZs5wxCbsmqvQczr3XCyTwaDZVQg==",
- "license": "MIT",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-8.0.2.tgz",
+ "integrity": "sha512-WXs8YB8B9eEaPZz+bcdY6t2nForF1FLoj/JU0Dl9RRgQnddnS98FEEyDooQhaY7wivr000j4+SC1FyeJkrFO7A==",
"peerDependencies": {
- "@capacitor/core": "^6.0.0"
+ "@capacitor/core": ">=8.0.0"
}
},
"node_modules/@csstools/color-helpers": {
@@ -2875,6 +2891,11 @@
"@babel/types": "^7.28.2"
}
},
+ "node_modules/@types/emscripten": {
+ "version": "1.41.5",
+ "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz",
+ "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q=="
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -3331,6 +3352,14 @@
"node": "18 || 20 || >=22"
}
},
+ "node_modules/barcode-detector": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-3.2.0.tgz",
+ "integrity": "sha512-MrT5TT058ptG5YB157pHLfXKVpp0BKEfQBOb8QvzTbatzmLDu85JJ0Gd/sCYwbwdwStJvxsYflrSN6D6E4Ndyw==",
+ "dependencies": {
+ "zxing-wasm": "3.1.0"
+ }
+ },
"node_modules/baseline-browser-mapping": {
"version": "2.9.11",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
@@ -6805,6 +6834,17 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tagged-tag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
+ "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/temp-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
@@ -7833,6 +7873,32 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zxing-wasm": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-3.1.0.tgz",
+ "integrity": "sha512-5+3V1wPRx4gvbeLH2jB7n2cKrYJ1q4i3QgjnBUtrDPeqxJSi6BdzKJg4y6aF6bgW8zfntnYJyrkqFMevDhL2NA==",
+ "dependencies": {
+ "@types/emscripten": "^1.41.5",
+ "type-fest": "^5.7.0"
+ },
+ "peerDependencies": {
+ "@types/emscripten": ">=1.39.6"
+ }
+ },
+ "node_modules/zxing-wasm/node_modules/type-fest": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz",
+ "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==",
+ "dependencies": {
+ "tagged-tag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
}
}
diff --git a/frontend/package.json b/frontend/package.json
index 3c5fed4..6373ebd 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -9,10 +9,12 @@
"test": "vitest"
},
"dependencies": {
- "@capacitor/app": "^6.0.3",
- "@capacitor/core": "^6.2.1",
- "@capacitor/splash-screen": "^6.0.4",
- "@capacitor/status-bar": "^6.0.3",
+ "@capacitor-mlkit/barcode-scanning": "^8.1.0",
+ "@capacitor/app": "^8.1.0",
+ "@capacitor/core": "^8.4.1",
+ "@capacitor/splash-screen": "^8.0.1",
+ "@capacitor/status-bar": "^8.0.2",
+ "barcode-detector": "^3.2.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
diff --git a/frontend/src/App.css b/frontend/src/App.css
index 08b8f97..2b5129f 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -66,6 +66,28 @@
text-align: center;
margin-bottom: 4rem;
animation: fadeInDown 0.8s ease-out;
+ position: relative;
+}
+
+.back-to-home-btn {
+ position: absolute;
+ left: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ background: var(--surface-muted);
+ border: 1px solid var(--border);
+ color: var(--text-muted);
+ font-size: 0.88rem;
+ font-weight: 600;
+ padding: 0.5rem 1rem;
+ border-radius: 999px;
+ cursor: pointer;
+ transition: color 0.2s, background 0.2s;
+}
+
+.back-to-home-btn:hover {
+ color: var(--text-main);
+ background: var(--surface-card);
}
.app-header h1 {
diff --git a/frontend/src/App.test.jsx b/frontend/src/App.test.jsx
index 294c882..078a189 100644
--- a/frontend/src/App.test.jsx
+++ b/frontend/src/App.test.jsx
@@ -11,9 +11,29 @@ afterEach(() => {
vi.useRealTimers()
})
-describe('PublicView', () => {
- it('renders search bar on load with no results', () => {
+// Helper: navigate from HomeView to the search screen
+async function navigateToSearch() {
+ fireEvent.click(screen.getByRole('button', { name: /manual search/i }))
+}
+
+describe('HomeView', () => {
+ it('renders two action buttons on the home screen', () => {
render()
+ expect(screen.getByRole('button', { name: /scan tsi/i })).toBeInTheDocument()
+ expect(screen.getByRole('button', { name: /manual search/i })).toBeInTheDocument()
+ })
+
+ it('navigates to search screen when Manual Search is clicked', async () => {
+ render()
+ await navigateToSearch()
+ expect(screen.getByPlaceholderText(/search for a medicine/i)).toBeInTheDocument()
+ })
+})
+
+describe('PublicView (search screen)', () => {
+ it('renders search bar on load with no results', async () => {
+ render()
+ await navigateToSearch()
expect(screen.getByPlaceholderText(/search for a medicine/i)).toBeInTheDocument()
expect(screen.queryByRole('list')).not.toBeInTheDocument()
})
@@ -21,6 +41,7 @@ describe('PublicView', () => {
it('does not fetch for queries shorter than 2 chars', async () => {
const fetchMock = vi.spyOn(globalThis, 'fetch')
render()
+ await navigateToSearch()
fireEvent.change(screen.getByPlaceholderText(/search for a medicine/i), {
target: { value: 'a' },
@@ -42,6 +63,7 @@ describe('PublicView', () => {
})
render()
+ await navigateToSearch()
fireEvent.change(screen.getByPlaceholderText(/search for a medicine/i), {
target: { value: 'ibu' },
@@ -63,6 +85,7 @@ describe('PublicView', () => {
})
render()
+ await navigateToSearch()
const input = screen.getByPlaceholderText(/search for a medicine/i)
fireEvent.change(input, { target: { value: 'ibu' } })
@@ -75,3 +98,4 @@ describe('PublicView', () => {
expect(screen.queryByText('Ibuprofeno 400mg')).not.toBeInTheDocument()
})
})
+
diff --git a/frontend/src/views/HomeView.css b/frontend/src/views/HomeView.css
new file mode 100644
index 0000000..c7a8486
--- /dev/null
+++ b/frontend/src/views/HomeView.css
@@ -0,0 +1,292 @@
+/* ============================================================
+ HomeView.css — Premium home page styles
+ ============================================================ */
+
+.home-container {
+ min-height: 100dvh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 2rem 1.5rem calc(5rem + env(safe-area-inset-bottom));
+ gap: 2.5rem;
+ animation: fadeInUp 0.7s ease-out;
+}
+
+/* ── Header ─────────────────────────────────────────────── */
+.home-header {
+ text-align: center;
+ max-width: 34rem;
+}
+
+.home-logo {
+ font-size: clamp(2.6rem, 7vw, 4rem);
+ font-weight: 900;
+ color: var(--text-main);
+ letter-spacing: -0.04em;
+ line-height: 1;
+ margin-bottom: 0.9rem;
+}
+
+.home-logo::after {
+ content: "";
+ display: block;
+ width: 3rem;
+ height: 4px;
+ margin: 0.85rem auto 0;
+ background: linear-gradient(90deg, var(--primary), var(--primary-hover));
+ border-radius: 2px;
+}
+
+.home-subtitle {
+ font-size: 1.1rem;
+ color: var(--text-muted);
+ font-weight: 400;
+ line-height: 1.55;
+}
+
+/* ── Card Grid ──────────────────────────────────────────── */
+.home-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 1.25rem;
+ width: 100%;
+ max-width: 54rem;
+}
+
+/* ── Base Card ──────────────────────────────────────────── */
+.home-card {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ gap: 1.2rem;
+ padding: 2rem 1.75rem 1.6rem;
+ border-radius: 20px;
+ border: 1px solid var(--glass-border);
+ background: var(--glass-bg);
+ box-shadow: var(--glass-shadow);
+ cursor: pointer;
+ text-align: left;
+ overflow: hidden;
+ transition:
+ transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1),
+ box-shadow 0.25s ease,
+ border-color 0.25s ease;
+}
+
+.home-card::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ border-radius: inherit;
+ pointer-events: none;
+}
+
+.home-card:hover {
+ transform: translateY(-5px) scale(1.015);
+ box-shadow:
+ 0 16px 40px rgba(28, 25, 23, 0.14),
+ 0 4px 12px rgba(28, 25, 23, 0.08);
+}
+
+.home-card:hover::before {
+ opacity: 1;
+}
+
+.home-card:active {
+ transform: translateY(-2px) scale(1.005);
+}
+
+/* ── Scan Card Accent ───────────────────────────────────── */
+.scan-card {
+ background: linear-gradient(
+ 145deg,
+ rgba(255, 255, 255, 0.97) 0%,
+ rgba(240, 253, 250, 0.97) 100%
+ );
+ border-color: rgba(15, 118, 110, 0.22);
+}
+
+.scan-card::before {
+ background: radial-gradient(
+ ellipse at top left,
+ rgba(15, 118, 110, 0.08) 0%,
+ transparent 70%
+ );
+}
+
+.scan-card:hover {
+ border-color: rgba(15, 118, 110, 0.45);
+ box-shadow:
+ 0 16px 40px rgba(15, 118, 110, 0.18),
+ 0 4px 12px rgba(15, 118, 110, 0.12);
+}
+
+/* ── Search Card Accent ─────────────────────────────────── */
+.search-card {
+ background: linear-gradient(
+ 145deg,
+ rgba(255, 255, 255, 0.97) 0%,
+ rgba(245, 245, 244, 0.97) 100%
+ );
+}
+
+.search-card:hover {
+ border-color: rgba(71, 85, 105, 0.35);
+ box-shadow:
+ 0 16px 40px rgba(28, 25, 23, 0.12),
+ 0 4px 12px rgba(28, 25, 23, 0.06);
+}
+
+/* ── Badge ──────────────────────────────────────────────── */
+.card-badge {
+ position: absolute;
+ top: 1.1rem;
+ right: 1.1rem;
+ background: linear-gradient(135deg, var(--primary), var(--primary-hover));
+ color: #fff;
+ font-size: 0.68rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ padding: 0.28rem 0.65rem;
+ border-radius: 999px;
+ box-shadow: 0 2px 8px rgba(15, 118, 110, 0.35);
+}
+
+/* ── Icon Container ─────────────────────────────────────── */
+.card-icon-container {
+ position: relative;
+ width: 4rem;
+ height: 4rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.card-icon {
+ font-size: 2.4rem;
+ line-height: 1;
+ position: relative;
+ z-index: 1;
+ filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.12));
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+
+.home-card:hover .card-icon {
+ transform: scale(1.18) rotate(-4deg);
+}
+
+/* Pulse rings on the Scan card */
+.pulse-ring,
+.pulse-ring-outer {
+ position: absolute;
+ inset: 0;
+ border-radius: 50%;
+ border: 2px solid rgba(15, 118, 110, 0.4);
+ animation: pulse-ring 2.2s ease-out infinite;
+ pointer-events: none;
+}
+
+.pulse-ring-outer {
+ animation-delay: 0.7s;
+ border-color: rgba(15, 118, 110, 0.2);
+}
+
+@keyframes pulse-ring {
+ 0% { transform: scale(0.85); opacity: 0.7; }
+ 70% { transform: scale(1.6); opacity: 0; }
+ 100% { transform: scale(1.6); opacity: 0; }
+}
+
+/* ── Card Content ───────────────────────────────────────── */
+.card-content h3 {
+ font-size: 1.4rem;
+ font-weight: 800;
+ color: var(--text-main);
+ letter-spacing: -0.02em;
+ margin-bottom: 0.5rem;
+}
+
+.card-content p {
+ font-size: 0.95rem;
+ color: var(--text-muted);
+ line-height: 1.55;
+}
+
+/* ── Card Action Footer ─────────────────────────────────── */
+.card-action {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: auto;
+ padding-top: 0.8rem;
+ border-top: 1px solid var(--border);
+ font-size: 0.9rem;
+ font-weight: 600;
+ color: var(--primary);
+}
+
+.scan-card .card-action {
+ color: var(--primary);
+}
+
+.search-card .card-action {
+ color: var(--text-muted);
+}
+
+.search-card:hover .card-action {
+ color: var(--text-main);
+}
+
+.action-arrow {
+ transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
+ font-size: 1.1rem;
+}
+
+.home-card:hover .action-arrow {
+ transform: translateX(5px);
+}
+
+/* ── Footer ─────────────────────────────────────────────── */
+.home-footer {
+ max-width: 40rem;
+ text-align: center;
+}
+
+.home-footer p {
+ font-size: 0.8rem;
+ color: var(--text-muted);
+ line-height: 1.55;
+ opacity: 0.8;
+}
+
+/* ── Responsive ─────────────────────────────────────────── */
+@media (max-width: 640px) {
+ .home-container {
+ padding: 1.5rem 1rem calc(6rem + env(safe-area-inset-bottom));
+ gap: 1.75rem;
+ justify-content: flex-start;
+ padding-top: 2.5rem;
+ }
+
+ .home-grid {
+ grid-template-columns: 1fr;
+ gap: 1rem;
+ }
+
+ .home-card {
+ padding: 1.5rem 1.4rem 1.3rem;
+ gap: 0.9rem;
+ }
+
+ .card-content h3 {
+ font-size: 1.25rem;
+ }
+
+ .card-content p {
+ font-size: 0.88rem;
+ }
+}
diff --git a/frontend/src/views/HomeView.jsx b/frontend/src/views/HomeView.jsx
new file mode 100644
index 0000000..8bb2c62
--- /dev/null
+++ b/frontend/src/views/HomeView.jsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import './HomeView.css';
+
+function HomeView({ onScanClick, onSearchClick }) {
+ return (
+
+
+
💊 FarmaFinder
+
Find your medicine at nearby pharmacies quickly and easily.