Compare commits

..

1 commit

Author SHA1 Message Date
dependabot[bot]
801151d77c
Bump react-native-haptic-feedback from 2.3.4 to 3.0.0 in /mobile
Bumps [react-native-haptic-feedback](https://github.com/mkuczera/react-native-haptic-feedback) from 2.3.4 to 3.0.0.
- [Release notes](https://github.com/mkuczera/react-native-haptic-feedback/releases)
- [Changelog](https://github.com/mkuczera/react-native-haptic-feedback/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mkuczera/react-native-haptic-feedback/compare/v2.3.4...v3.0.0)

---
updated-dependencies:
- dependency-name: react-native-haptic-feedback
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 19:31:24 +00:00
21 changed files with 998 additions and 2989 deletions

View file

@ -56,20 +56,6 @@ updates:
open-pull-requests-limit: 3 open-pull-requests-limit: 3
- package-ecosystem: pip
directory: /lambdas/suggestions
schedule:
interval: weekly
open-pull-requests-limit: 3
- package-ecosystem: pip
directory: /lambdas/oss-index-creator
schedule:
interval: weekly
open-pull-requests-limit: 3
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: / directory: /
schedule: schedule:

View file

@ -21,7 +21,6 @@ jobs:
with: with:
working-directory: web working-directory: web
cache-dependency-path: web/package-lock.json cache-dependency-path: web/package-lock.json
node-version: "24"
run-cdk-synth: false run-cdk-synth: false
run-conventions-check: false run-conventions-check: false
@ -39,7 +38,6 @@ jobs:
with: with:
working-directory: mobile working-directory: mobile
cache-dependency-path: mobile/package-lock.json cache-dependency-path: mobile/package-lock.json
node-version: "24"
run-cdk-synth: false run-cdk-synth: false
run-conventions-check: false run-conventions-check: false
@ -49,7 +47,6 @@ jobs:
with: with:
working-directory: infra working-directory: infra
cache-dependency-path: infra/package-lock.json cache-dependency-path: infra/package-lock.json
node-version: "24"
dotnet-version: "8.0.x" dotnet-version: "8.0.x"
dotnet-publish-project: api/src/ProposalSystem.Api/ProposalSystem.Api.csproj dotnet-publish-project: api/src/ProposalSystem.Api/ProposalSystem.Api.csproj
run-typecheck: false run-typecheck: false

View file

@ -12,10 +12,6 @@ concurrency:
group: deploy-mobile group: deploy-mobile
cancel-in-progress: false cancel-in-progress: false
permissions:
id-token: write
contents: read
jobs: jobs:
deploy-ios: deploy-ios:
name: Build & Upload to TestFlight name: Build & Upload to TestFlight

View file

@ -3,17 +3,11 @@ name: Deploy
on: on:
push: push:
branches: [main] branches: [main]
paths-ignore:
- "mobile/**"
concurrency: concurrency:
group: deploy-backend group: deploy-backend
cancel-in-progress: false cancel-in-progress: false
permissions:
id-token: write
contents: read
jobs: jobs:
deploy: deploy:
name: Deploy to AWS name: Deploy to AWS

View file

@ -9,7 +9,7 @@ Monorepo with five primary services:
- **.NET 8 API** -- Clean Architecture REST API hosted on Lambda behind API Gateway - **.NET 8 API** -- Clean Architecture REST API hosted on Lambda behind API Gateway
- **React 19 Web** -- MUI v7 admin/dispatcher workspace served via CloudFront + S3 - **React 19 Web** -- MUI v7 admin/dispatcher workspace served via CloudFront + S3
- **React Native Mobile** -- iOS-first field app for dispatchers (offline-capable) - **React Native Mobile** -- iOS-first field app for dispatchers (offline-capable)
- **Python Lambdas** -- PDF extraction, PDF generation, library ingestion, AI suggestions, AOSS index provisioning - **Python Lambdas** -- PDF extraction, PDF generation, library ingestion, AI suggestions
- **CDK Infrastructure** -- Three TypeScript stacks managing all AWS resources - **CDK Infrastructure** -- Three TypeScript stacks managing all AWS resources
## Repository Structure ## Repository Structure
@ -41,12 +41,12 @@ proposal-system/
## AWS Resources ## AWS Resources
All resources are in **us-east-1** (account 328440206208). All resources are in **us-east-1** (account 328440206208). CDK stacks are defined but not yet deployed to AWS.
| CDK Stack | Key Resources | | CDK Stack | Key Resources |
|---|---| |---|---|
| `proposal-system-foundation` | RDS PostgreSQL 15 (t4g.small), S3 buckets, SQS queue + DLQ, Cognito user pool, Secrets Manager | | `proposal-system-foundation` | RDS PostgreSQL 15 (t4g.small), S3 buckets, SQS queue + DLQ, Cognito user pool, Secrets Manager |
| `proposal-system-compute` | API Gateway HTTP API, .NET 8 API Lambda, Python Lambdas (pdf-extract, pdf-generate, library-ingest, suggestions, oss-index-creator), OpenSearch Serverless collection, Bedrock KB | | `proposal-system-compute` | API Gateway HTTP API, .NET 8 API Lambda, Python Lambdas (pdf-extract, pdf-generate, library-ingest, suggestions), Bedrock KB |
| `proposal-system-frontend` | CloudFront distribution (S3 OAC) | | `proposal-system-frontend` | CloudFront distribution (S3 OAC) |
| Resource Type | Names | | Resource Type | Names |

View file

@ -21,7 +21,7 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.27" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.27" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.1" /> <PackageReference Include="FluentValidation.AspNetCore" Version="11.3.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.11" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.11" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.27" /> <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.11" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -12,7 +12,6 @@ import * as lambdaEventSources from 'aws-cdk-lib/aws-lambda-event-sources';
import * as bedrock from 'aws-cdk-lib/aws-bedrock'; import * as bedrock from 'aws-cdk-lib/aws-bedrock';
import * as opensearchserverless from 'aws-cdk-lib/aws-opensearchserverless'; import * as opensearchserverless from 'aws-cdk-lib/aws-opensearchserverless';
import * as logs from 'aws-cdk-lib/aws-logs'; import * as logs from 'aws-cdk-lib/aws-logs';
import * as cr from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs'; import { Construct } from 'constructs';
export interface ComputeStackProps extends cdk.StackProps { export interface ComputeStackProps extends cdk.StackProps {
@ -91,31 +90,8 @@ export class ComputeStack extends cdk.Stack {
resources: [`arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0`], resources: [`arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0`],
})); }));
// Lambda to pre-create the vector index (retries until AOSS access policy propagates) // OpenSearch Serverless data access policy
const indexCreatorFn = new lambda.Function(this, 'OssIndexCreator', { new opensearchserverless.CfnAccessPolicy(this, 'OssDataAccessPolicy', {
functionName: 'proposal-system-oss-index-creator',
runtime: lambda.Runtime.PYTHON_3_12,
architecture: lambda.Architecture.ARM_64,
handler: 'app.handler',
code: lambda.Code.fromAsset('../lambdas/oss-index-creator', {
bundling: {
image: lambda.Runtime.PYTHON_3_12.bundlingImage,
command: [
'bash', '-c',
'pip install -r requirements.txt -t /asset-output && cp -au . /asset-output',
],
},
}),
timeout: cdk.Duration.minutes(6),
logRetention: logs.RetentionDays.TWO_MONTHS,
});
indexCreatorFn.addToRolePolicy(new iam.PolicyStatement({
actions: ['aoss:APIAccessAll'],
resources: [ossCollection.attrArn],
}));
const ossDataAccessPolicy = new opensearchserverless.CfnAccessPolicy(this, 'OssDataAccessPolicy', {
name: 'proposal-system-kb-access', name: 'proposal-system-kb-access',
type: 'data', type: 'data',
policy: JSON.stringify([{ policy: JSON.stringify([{
@ -123,27 +99,11 @@ export class ComputeStack extends cdk.Stack {
{ ResourceType: 'collection', Resource: ['collection/proposal-system-kb'], Permission: ['aoss:*'] }, { ResourceType: 'collection', Resource: ['collection/proposal-system-kb'], Permission: ['aoss:*'] },
{ ResourceType: 'index', Resource: ['index/proposal-system-kb/*'], Permission: ['aoss:*'] }, { ResourceType: 'index', Resource: ['index/proposal-system-kb/*'], Permission: ['aoss:*'] },
], ],
Principal: [kbRole.roleArn, indexCreatorFn.role!.roleArn], Principal: [kbRole.roleArn, `arn:aws:iam::${this.account}:root`],
}]), }]),
}); });
ossDataAccessPolicy.addDependency(ossCollection);
const indexProvider = new cr.Provider(this, 'OssIndexProvider', {
onEventHandler: indexCreatorFn,
});
const ossIndex = new cdk.CustomResource(this, 'OssIndex', {
serviceToken: indexProvider.serviceToken,
properties: {
Endpoint: ossCollection.attrCollectionEndpoint,
IndexName: 'proposal-system-index',
VectorField: 'embedding',
TextField: 'text',
MetadataField: 'metadata',
},
});
ossIndex.node.addDependency(ossDataAccessPolicy);
// Bedrock Knowledge Base
const knowledgeBase = new bedrock.CfnKnowledgeBase(this, 'KnowledgeBase', { const knowledgeBase = new bedrock.CfnKnowledgeBase(this, 'KnowledgeBase', {
name: 'proposal-system-kb', name: 'proposal-system-kb',
roleArn: kbRole.roleArn, roleArn: kbRole.roleArn,
@ -166,7 +126,6 @@ export class ComputeStack extends cdk.Stack {
}, },
}, },
}); });
knowledgeBase.node.addDependency(ossIndex);
// KB Data Source (S3 library bucket) // KB Data Source (S3 library bucket)
const dataSource = new bedrock.CfnDataSource(this, 'KbDataSource', { const dataSource = new bedrock.CfnDataSource(this, 'KbDataSource', {

View file

@ -8,6 +8,7 @@ then triggers a KB sync.
import json import json
import logging import logging
import os import os
import time
from datetime import datetime from datetime import datetime
import boto3 import boto3
@ -198,3 +199,27 @@ def _api_headers() -> dict:
if api_key: if api_key:
headers["X-Internal-Api-Key"] = api_key headers["X-Internal-Api-Key"] = api_key
return headers return headers
def _api_request(method: str, url: str, retries: int = 3, **kwargs) -> httpx.Response:
kwargs.setdefault("headers", _api_headers())
kwargs.setdefault("timeout", 10)
for attempt in range(retries):
try:
resp = httpx.request(method, url, **kwargs)
if resp.status_code < 500:
return resp
logger.warning(
"API returned %s on attempt %d for %s",
resp.status_code,
attempt + 1,
url,
)
except httpx.TransportError as e:
logger.warning(
"Transport error on attempt %d for %s: %s", attempt + 1, url, e
)
if attempt == retries - 1:
raise
time.sleep(min(2**attempt, 4))
return resp # type: ignore[possibly-undefined]

View file

@ -1,2 +1,2 @@
boto3>=1.43.10,<2.0 boto3>=1.43.9,<2.0
httpx>=0.28.1,<1.0 httpx>=0.27.0,<1.0

View file

@ -1,71 +0,0 @@
import time
import boto3
from opensearchpy import OpenSearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth
def handler(event, context):
if event["RequestType"] == "Delete":
return {"PhysicalResourceId": event.get("PhysicalResourceId", "none")}
props = event["ResourceProperties"]
endpoint = props["Endpoint"].replace("https://", "")
index_name = props["IndexName"]
vector_field = props["VectorField"]
text_field = props["TextField"]
metadata_field = props["MetadataField"]
session = boto3.Session()
credentials = session.get_credentials().get_frozen_credentials()
region = session.region_name
awsauth = AWS4Auth(
credentials.access_key,
credentials.secret_key,
region,
"aoss",
session_token=credentials.token,
)
client = OpenSearch(
hosts=[{"host": endpoint, "port": 443}],
http_auth=awsauth,
use_ssl=True,
verify_certs=True,
connection_class=RequestsHttpConnection,
timeout=30,
)
index_body = {
"settings": {"index": {"knn": True, "knn.algo_param.ef_search": 512}},
"mappings": {
"properties": {
vector_field: {
"type": "knn_vector",
"dimension": 1024,
"method": {
"engine": "faiss",
"name": "hnsw",
"space_type": "l2",
},
},
text_field: {"type": "text"},
metadata_field: {"type": "text"},
}
},
}
for attempt in range(30):
try:
client.indices.create(index=index_name, body=index_body)
return {"PhysicalResourceId": index_name}
except Exception as e:
error_str = str(e)
if "resource_already_exists_exception" in error_str:
return {"PhysicalResourceId": index_name}
if "403" in error_str and attempt < 29:
time.sleep(10)
continue
raise
raise Exception("Timeout waiting for AOSS access policy propagation")

View file

@ -1,3 +0,0 @@
opensearch-py>=3.2.0
requests-aws4auth>=1.3.2
requests>=2.34.2

View file

@ -9,6 +9,7 @@ import json
import logging import logging
import os import os
import tempfile import tempfile
import time
import boto3 import boto3
import httpx import httpx
@ -338,3 +339,27 @@ def _api_headers() -> dict:
if api_key: if api_key:
headers["X-Internal-Api-Key"] = api_key headers["X-Internal-Api-Key"] = api_key
return headers return headers
def _api_request(method: str, url: str, retries: int = 3, **kwargs) -> httpx.Response:
kwargs.setdefault("headers", _api_headers())
kwargs.setdefault("timeout", 10)
for attempt in range(retries):
try:
resp = httpx.request(method, url, **kwargs)
if resp.status_code < 500:
return resp
logger.warning(
"API returned %s on attempt %d for %s",
resp.status_code,
attempt + 1,
url,
)
except httpx.TransportError as e:
logger.warning(
"Transport error on attempt %d for %s: %s", attempt + 1, url, e
)
if attempt == retries - 1:
raise
time.sleep(min(2**attempt, 4))
return resp # type: ignore[possibly-undefined]

View file

@ -1,3 +1,3 @@
pdfplumber>=0.11.9,<1.0 pdfplumber>=0.11.9,<1.0
boto3>=1.43.10,<2.0 boto3>=1.43.9,<2.0
httpx>=0.28.1,<1.0 httpx>=0.27.0,<1.0

View file

@ -7,6 +7,7 @@ Triggered via SQS when an admin requests PDF generation.
import json import json
import logging import logging
import os import os
import time
from datetime import datetime from datetime import datetime
from io import BytesIO from io import BytesIO
@ -542,3 +543,27 @@ def _api_headers() -> dict:
if api_key: if api_key:
headers["X-Internal-Api-Key"] = api_key headers["X-Internal-Api-Key"] = api_key
return headers return headers
def _api_request(method: str, url: str, retries: int = 3, **kwargs) -> httpx.Response:
kwargs.setdefault("headers", _api_headers())
kwargs.setdefault("timeout", 10)
for attempt in range(retries):
try:
resp = httpx.request(method, url, **kwargs)
if resp.status_code < 500:
return resp
logger.warning(
"API returned %s on attempt %d for %s",
resp.status_code,
attempt + 1,
url,
)
except httpx.TransportError as e:
logger.warning(
"Transport error on attempt %d for %s: %s", attempt + 1, url, e
)
if attempt == retries - 1:
raise
time.sleep(min(2**attempt, 4))
return resp # type: ignore[possibly-undefined]

View file

@ -1,3 +1,3 @@
reportlab>=4.5.1,<5.0 reportlab>=4.5.1,<5.0
boto3>=1.43.10,<2.0 boto3>=1.43.9,<2.0
httpx>=0.28.1,<1.0 httpx>=0.27.0,<1.0

View file

@ -7,6 +7,7 @@ to generate line item suggestions for new proposals.
import json import json
import logging import logging
import os import os
import time
import boto3 import boto3
import httpx import httpx
@ -319,3 +320,27 @@ def _api_headers() -> dict:
if api_key: if api_key:
headers["X-Internal-Api-Key"] = api_key headers["X-Internal-Api-Key"] = api_key
return headers return headers
def _api_request(method: str, url: str, retries: int = 3, **kwargs) -> httpx.Response:
kwargs.setdefault("headers", _api_headers())
kwargs.setdefault("timeout", 10)
for attempt in range(retries):
try:
resp = httpx.request(method, url, **kwargs)
if resp.status_code < 500:
return resp
logger.warning(
"API returned %s on attempt %d for %s",
resp.status_code,
attempt + 1,
url,
)
except httpx.TransportError as e:
logger.warning(
"Transport error on attempt %d for %s: %s", attempt + 1, url, e
)
if attempt == retries - 1:
raise
time.sleep(min(2**attempt, 4))
return resp # type: ignore[possibly-undefined]

View file

@ -1,2 +1,2 @@
boto3>=1.35.0,<2.0 boto3>=1.35.0,<2.0
httpx>=0.28.1,<1.0 httpx>=0.27.0,<1.0

3638
mobile/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
"@tanstack/react-query": "^5.100.10", "@tanstack/react-query": "^5.100.10",
"axios": "^1.16.0", "axios": "^1.16.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-native": "^0.85.3", "react-native": "^0.79.0",
"react-native-app-auth": "^8.0.0", "react-native-app-auth": "^8.0.0",
"react-native-document-picker": "^9.3.0", "react-native-document-picker": "^9.3.0",
"react-native-haptic-feedback": "^3.0.0", "react-native-haptic-feedback": "^3.0.0",
@ -33,8 +33,6 @@
"react-redux": "^9.2.0" "react-redux": "^9.2.0"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/cli": "^20.1.3",
"@react-native-community/cli-platform-ios": "^20.1.3",
"@react-native/babel-preset": "^0.79.0", "@react-native/babel-preset": "^0.79.0",
"@react-native/metro-config": "^0.79.0", "@react-native/metro-config": "^0.79.0",
"@types/react": "^19.0.0", "@types/react": "^19.0.0",

71
web/package-lock.json generated
View file

@ -13,7 +13,7 @@
"@mui/icons-material": "^7.3.1", "@mui/icons-material": "^7.3.1",
"@mui/material": "^7.3.1", "@mui/material": "^7.3.1",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.11.2",
"@tanstack/react-query": "^5.100.11", "@tanstack/react-query": "^5.100.10",
"axios": "^1.16.0", "axios": "^1.16.0",
"react": "^19.1.1", "react": "^19.1.1",
"react-dom": "^19.1.1", "react-dom": "^19.1.1",
@ -1319,6 +1319,9 @@
"arm" "arm"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1333,6 +1336,9 @@
"arm" "arm"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1347,6 +1353,9 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1361,6 +1370,9 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1375,6 +1387,9 @@
"loong64" "loong64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1389,6 +1404,9 @@
"loong64" "loong64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1403,6 +1421,9 @@
"ppc64" "ppc64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1417,6 +1438,9 @@
"ppc64" "ppc64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1431,6 +1455,9 @@
"riscv64" "riscv64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1445,6 +1472,9 @@
"riscv64" "riscv64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1459,6 +1489,9 @@
"s390x" "s390x"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1473,6 +1506,9 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1487,6 +1523,9 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -1590,9 +1629,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tanstack/query-core": { "node_modules/@tanstack/query-core": {
"version": "5.100.11", "version": "5.100.10",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.11.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.10.tgz",
"integrity": "sha512-lmE0994apShXPj8CUxgx4ch5yUJhE9k/+tVwihBvPOyerACWdBocfFg24t8+0RhtlTd7tEgchDkhlCxNssvDxw==", "integrity": "sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@ -1600,12 +1639,12 @@
} }
}, },
"node_modules/@tanstack/react-query": { "node_modules/@tanstack/react-query": {
"version": "5.100.11", "version": "5.100.10",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.11.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.10.tgz",
"integrity": "sha512-J0f9s5x3LE1450nNNfYx+e/n0DMa0uOBdFJUy5r0RvmsXd4nB/n0rbHtHI1vYXhikNFan+wf51p6Tmp4c8ucrg==", "integrity": "sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.100.11" "@tanstack/query-core": "5.100.10"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@ -3061,6 +3100,22 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
},
"node_modules/yaml": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"extraneous": true,
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
} }
} }
} }

View file

@ -14,7 +14,7 @@
"@mui/icons-material": "^7.3.1", "@mui/icons-material": "^7.3.1",
"@mui/material": "^7.3.1", "@mui/material": "^7.3.1",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.11.2",
"@tanstack/react-query": "^5.100.11", "@tanstack/react-query": "^5.100.10",
"axios": "^1.16.0", "axios": "^1.16.0",
"react": "^19.1.1", "react": "^19.1.1",
"react-dom": "^19.1.1", "react-dom": "^19.1.1",