diff --git a/README.md b/README.md index c5febb7d..22ce495e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,291 @@ -# API V3 +# HackPSU API v3 -HackPSU's Official API Version 3 +Official backend API for the HackPSU hackathon event management platform. This internal service provides comprehensive functionality for managing hackathon participants, events, judging, sponsors, and administrative operations. + +## Project Overview + +HackPSU API v3 is a Node.js backend service that powers the HackPSU hackathon platform. The API manages the complete hackathon lifecycle including user registration, event scheduling, project judging, sponsor management, digital wallet integration, and real-time communication. Built for Penn State's annual hackathon, it serves hundreds of participants, organizers, judges, and sponsors. + +The system is designed for high availability during hackathon weekends while providing robust administrative tools for year-round event management and planning. + +### Target Users +- **Hackathon Participants**: Registration, event check-ins, project submissions +- **Organizers**: Event management, user administration, analytics +- **Judges**: Project evaluation and scoring +- **Sponsors**: Booth management and participant interaction +- **System Administrators**: Platform monitoring and configuration + +### Key Capabilities +- Complete user lifecycle management with Firebase authentication +- Event scheduling and QR-code based check-in system +- Project submission and judging workflow +- Digital wallet integration (Apple Wallet, Google Pay) for event passes +- Real-time notifications and WebSocket communication +- Sponsor management and interaction tracking +- Finance and reimbursement processing +- Inventory management for hackathon supplies +- Analytics and reporting for event metrics + +## Tech Stack + +### Core Framework +- **NestJS** - Enterprise-grade Node.js framework providing dependency injection, modular architecture, and TypeScript support +- **TypeScript** - Type-safe development with enhanced code reliability and developer experience +- **Node.js** - Runtime environment optimized for I/O intensive operations + +### Database & ORM +- **MySQL** - Primary relational database for structured data storage +- **Knex.js** - SQL query builder for database migrations and raw queries +- **Objection.js** - Object-relational mapper built on Knex providing model relationships and validation + +### Authentication & Backend Integration +- **Firebase Authentication** - OAuth integration and user identity management +- **Firebase Admin SDK** - Server-side Firebase operations and user management +- **Google Cloud Platform** - Cloud services integration including Firestore and messaging +- **Passport.js** - Authentication middleware with JWT strategy implementation + +### API Documentation & Validation +- **Swagger/OpenAPI** - Comprehensive API documentation with interactive testing interface +- **Class Validator** - Decorator-based request validation and transformation +- **Class Transformer** - Object serialization and deserialization + +### Email & Communication +- **SendGrid** - Transactional email delivery with template management +- **MJML** - Email template framework for responsive email design +- **Socket.IO** - Real-time bidirectional communication for live updates + +### Digital Wallet Integration +- **Passkit Generator** - Apple Wallet pass creation and management +- **Google Wallet API** - Google Pay pass integration for digital tickets + +### File Processing & Utilities +- **Multer** - File upload handling for resumes, receipts, and media +- **PDF-lib** - PDF document generation and manipulation +- **Archiver** - File compression for bulk downloads +- **Lodash** - Utility library for data manipulation +- **Luxon** - DateTime handling and timezone management + +### Development Tools +- **Jest** - Testing framework with coverage reporting +- **ESLint** - Code linting with TypeScript support +- **Prettier** - Code formatting standardization +- **Docker** - Containerization for consistent development and deployment environments + +## Architecture & Design Decisions + +### Modular NestJS Architecture +- Domain-driven module organization with clear separation of concerns +- Dependency injection container for loose coupling and testability +- Custom decorators for common functionality (authentication, validation, file uploads) +- Global exception filtering for consistent error handling + +### Authentication Strategy +- Firebase Authentication for frontend user management +- JWT-based API authentication with role-based access control +- Custom guards for protecting sensitive endpoints +- Role hierarchy: participants, organizers, judges, super admins + +### Database Design +- Relational data model with proper foreign key constraints +- Migration-based schema management using Knex.js +- Entity-relationship mapping through Objection.js models +- Optimized queries with eager loading for complex relationships + +### API Design Patterns +- RESTful endpoint structure with consistent HTTP methods +- Swagger documentation with comprehensive request/response schemas +- Request validation using class-validator decorators +- Standardized error responses and status codes + +### Real-time Features +- WebSocket gateway for live event updates and notifications +- Event-driven architecture for decoupled system components +- Firebase Cloud Messaging for push notifications + +### External Service Integration +- Abstracted service layers for third-party integrations +- Configuration management for environment-specific settings +- Retry logic and error handling for external API calls ## Getting Started -This project uses Node.js version 16 and uses yarn for its package manager. -To install yarn, run: `sudo npm install --global yarn`. +### Prerequisites +- Node.js 18+ and Yarn package manager +- MySQL 8.4+ database server +- Firebase project with Authentication enabled +- SendGrid account for email delivery +- Google Cloud Platform project (for GCP services) +- Apple Developer account (for Apple Wallet integration) + +### Installation + +1. Clone the repository and install dependencies: +```bash +git clone +cd apiv3 +yarn install +``` + +2. Set up the database: +```bash +# Start MySQL with Docker Compose +docker-compose up db -d + +# Run database migrations +yarn knex migrate:latest +``` + +3. Configure environment variables: +```bash +# Copy example environment file +cp .env.example .env + +# Configure required variables: +# - Firebase configuration +# - Database connection +# - SendGrid API keys +# - GCP service account +# - Apple certificates +``` + +4. Start the development server: +```bash +yarn start:dev +``` + +### Available Scripts +- `yarn start:dev` - Development server with hot reload +- `yarn build` - Build production bundle +- `yarn start:prod` - Run production server +- `yarn test` - Run unit tests +- `yarn test:e2e` - Run end-to-end tests +- `yarn lint` - Lint and fix code style issues +- `yarn format` - Format code with Prettier + +### Environment Setup +Configure the following environment variables: +- `DATABASE_URL` - MySQL connection string +- `FIREBASE_CONFIG` - Firebase service account configuration +- `SENDGRID_API_KEY` - SendGrid API key for email delivery +- `GCP_CREDENTIALS` - Google Cloud service account credentials +- `APPLE_CERTIFICATES` - Apple Wallet certificate paths +- `PORT` - Server port (default: 3000) + +## Project Structure + +``` +src/ +├── common/ # Shared modules and utilities +│ ├── apple/ # Apple Wallet integration services +│ ├── config/ # Configuration management +│ ├── gcp/ # Google Cloud Platform services +│ │ ├── auth/ # Firebase authentication +│ │ ├── firestore/ # Firestore database integration +│ │ ├── messaging/ # Firebase Cloud Messaging +│ │ └── wallet/ # Google Wallet integration +│ ├── objection/ # Database ORM configuration +│ ├── sendgrid/ # Email service integration +│ └── validation/ # Custom validation pipes +├── entities/ # Database entity models (ORM) +│ ├── user.entity.ts # User profile and authentication +│ ├── event.entity.ts # Events and scheduling +│ ├── project.entity.ts # Hackathon project submissions +│ ├── score.entity.ts # Judging scores and criteria +│ └── ... # Additional domain entities +├── modules/ # Feature modules (controllers + services) +│ ├── user/ # User management and profiles +│ ├── event/ # Event scheduling and management +│ ├── judging/ # Project evaluation system +│ ├── registration/ # Hackathon registration flow +│ ├── sponsor/ # Sponsor management +│ ├── finance/ # Reimbursement processing +│ ├── inventory/ # Supply and equipment tracking +│ ├── notification/ # Push notifications and alerts +│ ├── analytics/ # Event metrics and reporting +│ └── socket/ # Real-time communication +├── templates/ # Email and document templates +└── main.ts # Application bootstrap +db/ +├── migrations/ # Database schema migrations +test/ # End-to-end and integration tests +``` + +## Key Features + +### User Management +- Firebase-based authentication with role management +- Comprehensive user profiles with hackathon-specific fields +- Resume upload and processing for sponsor access +- LinkedIn integration for professional networking + +### Event System +- Dynamic event scheduling with location mapping +- QR-code based check-in system for attendance tracking +- Workshop management with presenter information +- Real-time event updates via WebSocket connections + +### Judging Platform +- Multi-criteria project evaluation system +- Judge assignment and conflict resolution +- Score aggregation and ranking algorithms +- Real-time judging progress tracking + +### Digital Wallet Integration +- Apple Wallet pass generation for event tickets +- Google Pay integration for seamless mobile access +- Dynamic pass updates with event information +- Barcode generation for physical check-ins + +### Communication System +- SendGrid-powered email campaigns with MJML templates +- Push notifications via Firebase Cloud Messaging +- Real-time WebSocket updates for live features +- Automated notification workflows + +### Administrative Tools +- Comprehensive analytics dashboard +- Finance module for reimbursement processing +- Inventory tracking for hackathon supplies +- Sponsor interaction management + +## Deployment + +The application is containerized with Docker for consistent deployment across environments: + +```bash +# Build production image +docker build --target production -t hackpsu-api . + +# Deploy with environment variables +docker run -p 3000:3000 --env-file .env hackpsu-api +``` + +For production deployment, ensure proper configuration of: +- Database connection pooling +- Firebase service account permissions +- SendGrid domain verification +- Apple Developer certificate provisioning +- Load balancer configuration for WebSocket support + +## Contributing + +### Code Standards +- TypeScript strict mode enabled for type safety +- ESLint configuration with Prettier integration +- Comprehensive unit test coverage required +- API endpoints must include Swagger documentation +- Database changes require migration files + +### Development Workflow +- Feature branches with descriptive naming +- Pull request reviews required for main branch +- Automated testing pipeline with CI/CD integration +- Environment-specific configuration management +- Security review for authentication-related changes -Then, use yarn to install dependencies by running the `yarn` command in the top level of this repository. +### Architecture Guidelines +- Follow NestJS module structure and dependency injection patterns +- Implement proper error handling with custom exception filters +- Use decorators for cross-cutting concerns (auth, validation, logging) +- Maintain separation between business logic and data access layers +- Design APIs with backward compatibility considerations diff --git a/package.json b/package.json index 58728704..40e905a0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "fast-xml-parser": "^5.2.3", "firebase": "^12.0.0", "firebase-admin": "^13.0.2", - "googleapis": "^154.0.0", + "googleapis": "^155.0.0", "handlebars": "^4.7.8", "jsonwebtoken": "^9.0.2", "jwt-decode": "^4.0.0", diff --git a/src/modules/judging/project.controller.ts b/src/modules/judging/project.controller.ts index 8a4899ff..e9f7b9fa 100644 --- a/src/modules/judging/project.controller.ts +++ b/src/modules/judging/project.controller.ts @@ -42,7 +42,6 @@ export class ProjectController { ) {} @Get("/") - @Roles(Role.TEAM) @ApiDoc({ summary: "Get All Projects", response: { diff --git a/yarn.lock b/yarn.lock index 5e2a19a0..9cd0534f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -423,10 +423,10 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-3.1.1.tgz#af3aea7f1e52ec916d8b5c9dcc0f09d4c060a3fc" integrity sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw== -"@firebase/ai@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@firebase/ai/-/ai-2.0.0.tgz#c0324b48c2451b28d621c96517e056ab67576dc4" - integrity sha512-N/aSHjqOpU+KkYU3piMkbcuxzvqsOvxflLUXBAkYAPAz8wjE2Ye3BQDgKHEYuhMmEWqj6LFgEBUN8wwc6dfMTw== +"@firebase/ai@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@firebase/ai/-/ai-2.1.0.tgz#5da826e6a17889b8a8f896470e34450e8d22fa3a" + integrity sha512-4HvFr4YIzNFh0MowJLahOjJDezYSTjQar0XYVu/sAycoxQ+kBsfXuTPRLVXCYfMR5oNwQgYe4Q2gAOYKKqsOyA== dependencies: "@firebase/app-check-interop-types" "0.3.3" "@firebase/component" "0.7.0" @@ -493,12 +493,12 @@ "@firebase/util" "1.13.0" tslib "^2.1.0" -"@firebase/app-compat@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.5.0.tgz#7463e9fb8d84706787773d3660accedff4479d05" - integrity sha512-nUnNpOeRj0KZzVzHsyuyrmZKKHfykZ8mn40FtG28DeSTWeM5b/2P242Va4bmQpJsy5y32vfv50+jvdckrpzy7Q== +"@firebase/app-compat@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.5.1.tgz#38deea05daca4d5903a77e638f016aca0d2990e1" + integrity sha512-BEy1L6Ufd85ZSP79HDIv0//T9p7d5Bepwy+2mKYkgdXBGKTbFm2e2KxyF1nq4zSQ6RRBxWi0IY0zFVmoBTZlUA== dependencies: - "@firebase/app" "0.14.0" + "@firebase/app" "0.14.1" "@firebase/component" "0.7.0" "@firebase/logger" "0.5.0" "@firebase/util" "1.13.0" @@ -509,10 +509,10 @@ resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.3.tgz#8408219eae9b1fb74f86c24e7150a148460414ad" integrity sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw== -"@firebase/app@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.14.0.tgz#7132e96df95e85783922fd09750f08ab2ebfd699" - integrity sha512-APIAeKvRNFWKJLjIL8wLDjh7u8g6ZjaeVmItyqSjCdEkJj14UuVlus74D8ofsOMWh45HEwxwkd96GYbi+CImEg== +"@firebase/app@0.14.1": + version "0.14.1" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.14.1.tgz#7840b9374f11b2f6585e8bc118870271b6928e39" + integrity sha512-jxTrDbxnGoX7cGz7aP9E7v9iKvBbQfZ8Gz4TH3SfrrkcyIojJM3+hJnlbGnGxHrABts844AxRcg00arMZEyA6Q== dependencies: "@firebase/component" "0.7.0" "@firebase/logger" "0.5.0" @@ -720,14 +720,14 @@ idb "7.1.1" tslib "^2.1.0" -"@firebase/performance-compat@0.2.21": - version "0.2.21" - resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.21.tgz#60f04ecb5ff98b5d84a7a932f2e8294aae711c72" - integrity sha512-OQfYRsIQiEf9ez1SOMLb5TRevBHNIyA2x1GI1H10lZ432W96AK5r4LTM+SNApg84dxOuHt6RWSQWY7TPWffKXg== +"@firebase/performance-compat@0.2.22": + version "0.2.22" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.22.tgz#1c24ea360b03cfef831bdf379b4fc7080f412741" + integrity sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg== dependencies: "@firebase/component" "0.7.0" "@firebase/logger" "0.5.0" - "@firebase/performance" "0.7.8" + "@firebase/performance" "0.7.9" "@firebase/performance-types" "0.2.3" "@firebase/util" "1.13.0" tslib "^2.1.0" @@ -737,10 +737,10 @@ resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.2.3.tgz#5ce64e90fa20ab5561f8b62a305010cf9fab86fb" integrity sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ== -"@firebase/performance@0.7.8": - version "0.7.8" - resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.7.8.tgz#a3e5ff36070e0f26e59f84fcd8faf7a8ee77c677" - integrity sha512-k6xfNM/CdTl4RaV4gT/lH53NU+wP33JiN0pUeNBzGVNvfXZ3HbCkoISE3M/XaiOwHgded1l6XfLHa4zHgm0Wyg== +"@firebase/performance@0.7.9": + version "0.7.9" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.7.9.tgz#7e3a072b1542f0df3f502684a38a0516b0d72cab" + integrity sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ== dependencies: "@firebase/component" "0.7.0" "@firebase/installations" "0.6.19" @@ -1462,9 +1462,9 @@ webpack-node-externals "3.0.0" "@nestjs/common@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-11.1.5.tgz#bc491d049e21f91216189b06e56f801730a8a3d1" - integrity sha512-DQpWdr3ShO0BHWkHl3I4W/jR6R3pDtxyBlmrpTuZF+PXxQyBXNvsUne0Wyo6QHPEDi+pAz9XchBFoKbqOhcdTg== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-11.1.6.tgz#704ae26f09ccd135bf3e6f44b6ef4e3407ea3c54" + integrity sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ== dependencies: uid "2.0.2" file-type "21.0.0" @@ -1482,9 +1482,9 @@ lodash "4.17.21" "@nestjs/core@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-11.1.5.tgz#98fff1a0b47b36a1939f6d9f6c899c085e470e25" - integrity sha512-Qr25MEY9t8VsMETy7eXQ0cNXqu0lzuFrrTr+f+1G57ABCtV5Pogm7n9bF71OU2bnkDD32Bi4hQLeFR90cku3Tw== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-11.1.6.tgz#9d54882f121168b2fa2b07fa1db0858161a80626" + integrity sha512-siWX7UDgErisW18VTeJA+x+/tpNZrJewjTBsRPF3JVxuWRuAB1kRoiJcxHgln8Lb5UY9NdvklITR84DUEXD0Cg== dependencies: uid "2.0.2" "@nuxt/opencollective" "0.4.1" @@ -1504,9 +1504,9 @@ integrity sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ== "@nestjs/platform-express@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-11.1.5.tgz#93a609c6ffd80460b561220d469e5e1bd11f732f" - integrity sha512-OsoiUBY9Shs5IG3uvDIt9/IDfY5OlvWBESuB/K4Eun8xILw1EK5d5qMfC3d2sIJ+kA3l+kBR1d/RuzH7VprLIg== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-11.1.6.tgz#9b1dcf82a3b3fdd5761c918ad664aff83e4eacc7" + integrity sha512-HErwPmKnk+loTq8qzu1up+k7FC6Kqa8x6lJ4cDw77KnTxLzsCaPt+jBvOq6UfICmfqcqCCf3dKXg+aObQp+kIQ== dependencies: cors "2.8.5" express "5.1.0" @@ -1515,9 +1515,9 @@ tslib "2.8.1" "@nestjs/platform-socket.io@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/platform-socket.io/-/platform-socket.io-11.1.5.tgz#07538470e8680d105c55f5cd550d0c2cd35944c3" - integrity sha512-DY3zNY+BjbrYpV/t8HL8ptrusrWK8J0cfkfY1iZsfCd+0/1+j8IKno+QMLkerNQAZ7/Frh5tkaKHVwWk18TkMw== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/platform-socket.io/-/platform-socket.io-11.1.6.tgz#5039a0497b53f0eb8905666ca7e7af9c728248b3" + integrity sha512-ozm+OKiRiFLNQdFLA3ULDuazgdVaPrdRdgtG/+404T7tcROXpbUuFL0eEmWJpG64CxMkBNwamclUSH6J0AeU7A== dependencies: socket.io "4.8.1" tslib "2.8.1" @@ -1546,16 +1546,16 @@ swagger-ui-dist "5.21.0" "@nestjs/testing@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-11.1.5.tgz#8a95502b8eb0349c4f3d7cf355e441291084733e" - integrity sha512-ZYRYF750SefmuIo7ZqPlHDcin1OHh6My0OkOfGEFjrD9mJ0vMVIpwMTOOkpzCfCcpqUuxeHBuecpiIn+NLrQbQ== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-11.1.6.tgz#7f172a8024948dee4cb318acccfff31c1356f338" + integrity sha512-srYzzDNxGvVCe1j0SpTS9/ix75PKt6Sn6iMaH1rpJ6nj2g8vwNrhK0CoJJXvpCYgrnI+2WES2pprYnq8rAMYHA== dependencies: tslib "2.8.1" "@nestjs/websockets@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@nestjs/websockets/-/websockets-11.1.5.tgz#b855130b762d15203e0b20e7a83b60d30eac26d0" - integrity sha512-mAM11HwyS7aeSUbXdOqHbNCRoHwB0OOb+cmx5sgxvszhdG0Y6bwR60nKA4+EXL9xUEeWoxmbfLmSHlTSIJ9GKA== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@nestjs/websockets/-/websockets-11.1.6.tgz#98984ddbbfb4a73ef57ef6cb706989275303b96b" + integrity sha512-jlBX5QpqhfEVfxkwxTesIjgl0bdhgFMoORQYzjRg1i+Z+Qouf4KmjNPv5DZE3DZRDg91E+3Bpn0VgW0Yfl94ng== dependencies: iterare "1.2.1" object-hash "3.0.0" @@ -2017,19 +2017,12 @@ dependencies: "@types/express" "*" -"@types/node@*": - version "24.1.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.1.0.tgz#0993f7dc31ab5cc402d112315b463e383d68a49c" - integrity sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w== +"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "24.2.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.2.0.tgz#cde712f88c5190006d6b069232582ecd1f94a760" + integrity sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw== dependencies: - undici-types "~7.8.0" - -"@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.7.0": - version "24.0.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.15.tgz#f34fbc973e7d64217106e0c59ed8761e6b51381e" - integrity sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA== - dependencies: - undici-types "~7.8.0" + undici-types "~7.10.0" "@types/node@^22.10.5", "@types/node@^22.8.7": version "22.17.0" @@ -2144,78 +2137,78 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^8.19.1": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz#6e5220d16f2691ab6d983c1737dd5b36e17641b7" - integrity sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA== + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz#c9afec1866ee1a6ea3d768b5f8e92201efbbba06" + integrity sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.38.0" - "@typescript-eslint/type-utils" "8.38.0" - "@typescript-eslint/utils" "8.38.0" - "@typescript-eslint/visitor-keys" "8.38.0" + "@typescript-eslint/scope-manager" "8.39.0" + "@typescript-eslint/type-utils" "8.39.0" + "@typescript-eslint/utils" "8.39.0" + "@typescript-eslint/visitor-keys" "8.39.0" graphemer "^1.4.0" ignore "^7.0.0" natural-compare "^1.4.0" ts-api-utils "^2.1.0" "@typescript-eslint/parser@^8.19.1": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.38.0.tgz#6723a5ea881e1777956b1045cba30be5ea838293" - integrity sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ== - dependencies: - "@typescript-eslint/scope-manager" "8.38.0" - "@typescript-eslint/types" "8.38.0" - "@typescript-eslint/typescript-estree" "8.38.0" - "@typescript-eslint/visitor-keys" "8.38.0" + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.39.0.tgz#c4b895d7a47f4cd5ee6ee77ea30e61d58b802008" + integrity sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg== + dependencies: + "@typescript-eslint/scope-manager" "8.39.0" + "@typescript-eslint/types" "8.39.0" + "@typescript-eslint/typescript-estree" "8.39.0" + "@typescript-eslint/visitor-keys" "8.39.0" debug "^4.3.4" -"@typescript-eslint/project-service@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.38.0.tgz#4900771f943163027fd7d2020a062892056b5e2f" - integrity sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg== +"@typescript-eslint/project-service@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.39.0.tgz#71cb29c3f8139f99a905b8705127bffc2ae84759" + integrity sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.38.0" - "@typescript-eslint/types" "^8.38.0" + "@typescript-eslint/tsconfig-utils" "^8.39.0" + "@typescript-eslint/types" "^8.39.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz#5a0efcb5c9cf6e4121b58f87972f567c69529226" - integrity sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ== +"@typescript-eslint/scope-manager@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz#ba4bf6d8257bbc172c298febf16bc22df4856570" + integrity sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A== dependencies: - "@typescript-eslint/types" "8.38.0" - "@typescript-eslint/visitor-keys" "8.38.0" + "@typescript-eslint/types" "8.39.0" + "@typescript-eslint/visitor-keys" "8.39.0" -"@typescript-eslint/tsconfig-utils@8.38.0", "@typescript-eslint/tsconfig-utils@^8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz#6de4ce224a779601a8df667db56527255c42c4d0" - integrity sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ== +"@typescript-eslint/tsconfig-utils@8.39.0", "@typescript-eslint/tsconfig-utils@^8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz#b2e87fef41a3067c570533b722f6af47be213f13" + integrity sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ== -"@typescript-eslint/type-utils@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz#a56cd84765fa6ec135fe252b5db61e304403a85b" - integrity sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg== +"@typescript-eslint/type-utils@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz#310ec781ae5e7bb0f5940bfd652573587f22786b" + integrity sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q== dependencies: - "@typescript-eslint/types" "8.38.0" - "@typescript-eslint/typescript-estree" "8.38.0" - "@typescript-eslint/utils" "8.38.0" + "@typescript-eslint/types" "8.39.0" + "@typescript-eslint/typescript-estree" "8.39.0" + "@typescript-eslint/utils" "8.39.0" debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.38.0", "@typescript-eslint/types@^8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.38.0.tgz#297351c994976b93c82ac0f0e206c8143aa82529" - integrity sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw== +"@typescript-eslint/types@8.39.0", "@typescript-eslint/types@^8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.39.0.tgz#80f010b7169d434a91cd0529d70a528dbc9c99c6" + integrity sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg== -"@typescript-eslint/typescript-estree@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz#82262199eb6778bba28a319e25ad05b1158957df" - integrity sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ== +"@typescript-eslint/typescript-estree@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz#b9477a5c47a0feceffe91adf553ad9a3cd4cb3d6" + integrity sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw== dependencies: - "@typescript-eslint/project-service" "8.38.0" - "@typescript-eslint/tsconfig-utils" "8.38.0" - "@typescript-eslint/types" "8.38.0" - "@typescript-eslint/visitor-keys" "8.38.0" + "@typescript-eslint/project-service" "8.39.0" + "@typescript-eslint/tsconfig-utils" "8.39.0" + "@typescript-eslint/types" "8.39.0" + "@typescript-eslint/visitor-keys" "8.39.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -2223,22 +2216,22 @@ semver "^7.6.0" ts-api-utils "^2.1.0" -"@typescript-eslint/utils@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.38.0.tgz#5f10159899d30eb92ba70e642ca6f754bddbf15a" - integrity sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg== +"@typescript-eslint/utils@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.39.0.tgz#dfea42f3c7ec85f9f3e994ff0bba8f3b2f09e220" + integrity sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ== dependencies: "@eslint-community/eslint-utils" "^4.7.0" - "@typescript-eslint/scope-manager" "8.38.0" - "@typescript-eslint/types" "8.38.0" - "@typescript-eslint/typescript-estree" "8.38.0" + "@typescript-eslint/scope-manager" "8.39.0" + "@typescript-eslint/types" "8.39.0" + "@typescript-eslint/typescript-estree" "8.39.0" -"@typescript-eslint/visitor-keys@8.38.0": - version "8.38.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz#a9765a527b082cb8fc60fd8a16e47c7ad5b60ea5" - integrity sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g== +"@typescript-eslint/visitor-keys@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz#5d619a6e810cdd3fd1913632719cbccab08bf875" + integrity sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA== dependencies: - "@typescript-eslint/types" "8.38.0" + "@typescript-eslint/types" "8.39.0" eslint-visitor-keys "^4.2.1" "@ungap/structured-clone@^1.3.0": @@ -3710,9 +3703,9 @@ eslint-config-prettier@^10.0.0: integrity sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w== eslint-plugin-prettier@^5.2.1: - version "5.5.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz#1f88e9220a72ac8be171eec5f9d4e4d529b5f4a0" - integrity sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w== + version "5.5.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz#9d61c4ea11de5af704d4edf108c82ccfa7f2e61c" + integrity sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg== dependencies: prettier-linter-helpers "^1.0.0" synckit "^0.11.7" @@ -4109,17 +4102,17 @@ firebase-admin@^13.0.2: "@google-cloud/storage" "^7.14.0" firebase@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-12.0.0.tgz#436ee1b97b64265f3e7d3b6b0ce4419cc9fe5ae9" - integrity sha512-KV+OrMJpi2uXlqL2zaCcXb7YuQbY/gMIWT1hf8hKeTW1bSumWaHT5qfmn0WTpHwKQa3QEVOtZR2ta9EchcmYuw== + version "12.1.0" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-12.1.0.tgz#38f9c019d0cfd2fdf6c268355a5819aeb559cd5d" + integrity sha512-oZucxvfWKuAW4eHHRqGKzC43fLiPqPwHYBHPRNsnkgonqYaq0VurYgqgBosRlEulW+TWja/5Tpo2FpUU+QrfEQ== dependencies: - "@firebase/ai" "2.0.0" + "@firebase/ai" "2.1.0" "@firebase/analytics" "0.10.18" "@firebase/analytics-compat" "0.2.24" - "@firebase/app" "0.14.0" + "@firebase/app" "0.14.1" "@firebase/app-check" "0.11.0" "@firebase/app-check-compat" "0.4.0" - "@firebase/app-compat" "0.5.0" + "@firebase/app-compat" "0.5.1" "@firebase/app-types" "0.9.3" "@firebase/auth" "1.11.0" "@firebase/auth-compat" "0.6.0" @@ -4134,8 +4127,8 @@ firebase@^12.0.0: "@firebase/installations-compat" "0.2.19" "@firebase/messaging" "0.12.23" "@firebase/messaging-compat" "0.2.23" - "@firebase/performance" "0.7.8" - "@firebase/performance-compat" "0.2.21" + "@firebase/performance" "0.7.9" + "@firebase/performance-compat" "0.2.22" "@firebase/remote-config" "0.6.6" "@firebase/remote-config-compat" "0.2.19" "@firebase/storage" "0.14.0" @@ -4434,6 +4427,19 @@ google-auth-library@^10.1.0: gtoken "^8.0.0" jws "^4.0.0" +google-auth-library@^10.2.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-10.2.1.tgz#9d2513dd92d797cd058a1696011b0cd4f0213b50" + integrity sha512-HMxFl2NfeHYnaL1HoRIN1XgorKS+6CDaM+z9LSSN+i/nKDDL4KFFEWogMXu7jV4HZQy2MsxpY+wA5XIf3w410A== + dependencies: + base64-js "^1.3.0" + ecdsa-sig-formatter "^1.0.11" + gaxios "^7.0.0" + gcp-metadata "^7.0.0" + google-logging-utils "^1.0.0" + gtoken "^8.0.0" + jws "^4.0.0" + google-auth-library@^9.14.2, google-auth-library@^9.3.0, google-auth-library@^9.6.3: version "9.15.1" resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.15.1.tgz#0c5d84ed1890b2375f1cd74f03ac7b806b392928" @@ -4485,12 +4491,12 @@ googleapis-common@^8.0.0: qs "^6.7.0" url-template "^2.0.8" -googleapis@^154.0.0: - version "154.1.0" - resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-154.1.0.tgz#2d44401ab6ebd8239ba74c9548c3b396da9e7eff" - integrity sha512-lsgKftflkjR+PNdKDjy5e4zZUQO3BMaNLO0Q91uvr9YCy3aOqtEwkDtfhcBguFtFLsqj+XjdfDu2on6rtHNvYg== +googleapis@^155.0.0: + version "155.0.0" + resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-155.0.0.tgz#7b0d41ad0cddf206b3e57f83b25420873d1403be" + integrity sha512-aGZrkCjd3UNatRDj/8NFumS3OtvkNVUn3PjeNydXGydi8U751V4KTXFAOivXKgNzMhGZXML6xzdybVVVKGkPJw== dependencies: - google-auth-library "^10.1.0" + google-auth-library "^10.2.0" googleapis-common "^8.0.0" gopd@^1.2.0: @@ -7416,9 +7422,9 @@ strnum@^2.1.0: integrity sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw== strtok3@^10.2.2: - version "10.3.2" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.2.tgz#7e5d14d27dc69c1319f74a91f137851e1a373910" - integrity sha512-or9w505RhhY66+uoe5YOC5QO/bRuATaoim3XTh+pGKx5VMWi/HDhMKuCjDLsLJouU2zg9Hf1nLPcNW7IHv80kQ== + version "10.3.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" + integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== dependencies: "@tokenizer/token" "^0.3.0" @@ -7585,9 +7591,9 @@ toidentifier@1.0.1: integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== token-types@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.0.3.tgz#684f4f40e0750078ec644c826207a2c160b827a8" - integrity sha512-IKJ6EzuPPWtKtEIEPpIdXv9j5j2LGJEYk0CKY2efgKoYKLBiZdh6iQkLVBow/CB3phyWAWCyk+bZeaimJn6uRQ== + version "6.0.4" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.0.4.tgz#1582ef6d1d77398cd738c87ea38dd5729fa49ec5" + integrity sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw== dependencies: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" @@ -7757,10 +7763,10 @@ undici-types@~6.21.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== -undici-types@~7.8.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" - integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== +undici-types@~7.10.0: + version "7.10.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350" + integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag== universalify@^2.0.0: version "2.0.1"