Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

286 unlock 4 implement key loyalty card contract #292

Merged
merged 36 commits into from
Apr 22, 2024

Conversation

sebpalluel
Copy link
Contributor

@sebpalluel sebpalluel commented Apr 4, 2024

Type

enhancement, other


Description

  • Refactored NftCollection to EventPassCollection for clarity.
  • Implemented PackCollection for deploying and managing packs.
  • Introduced LoyaltyCardCollection for loyalty card contract deployment and metadata management.
  • Updated GraphQL types and queries to support new webhook fields and nullable tokenId.
  • Enhanced error handling across event pass, pack, and loyalty card deployment.

Changes walkthrough

Relevant files
Enhancement
index.ts
Update GraphQL Types for Nullable Token IDs and Webhook Info

libs/gql/admin/types/src/generated/index.ts

  • Updated GraphQL types to handle nullable tokenId fields.
  • Adjusted types for webhook information to include signing keys.
  • +224/-28
    index.ts
    Update GraphQL Queries with Webhook Fields and Rename Documents

    libs/gql/admin/api/src/generated/index.ts

  • Modified GraphQL queries to include new webhook fields.
  • Adjusted document names for clarity and consistency.
  • +387/-30
    index.ts
    Refactor Event Pass Collection Deployment and Error Handling

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts

  • Refactored class name from NftCollection to EventPassCollection.
  • Implemented error handling improvements and code refactoring.
  • Added new methods for deploying event pass collections.
  • +48/-326
    index.ts
    Implement Pack Collection Deployment and Management           

    libs/nft/thirdweb-organizer-pack/src/lib/index.ts

  • Introduced PackCollection class for pack deployment and management.
  • Added methods for deploying packs and associating them with event
    passes.
  • +268/-0 
    index.ts
    Implement Loyalty Card Collection Deployment and Metadata Management

    libs/nft/thirdweb-organizer-loyalty-card/src/lib/index.ts

  • Introduced LoyaltyCardCollection class for loyalty card deployment.
  • Added methods for deploying loyalty card contracts and managing
    metadata.
  • +115/-0 
    Tests
    index.integration.test.ts
    Update Integration Tests for Event Pass Collection             

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts

  • Updated tests to reflect class name change to EventPassCollection.
  • Added new test cases for event pass collection deployment.
  • +49/-36 
    index.spec.ts
    Update Unit Tests for Event Pass Collection Refactoring   

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.spec.ts

  • Updated unit tests for EventPassCollection class.
  • Added tests for new deployment methods and error handling.
  • +78/-66 

    PR-Agent usage:
    Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    @sebpalluel sebpalluel linked an issue Apr 4, 2024 that may be closed by this pull request
    Copy link

    vercel bot commented Apr 4, 2024

    The latest updates on your projects. Learn more about Vercel for Git ↗︎

    Name Status Preview Comments Updated (UTC)
    back-office ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 22, 2024 1:45pm
    marketplace ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 22, 2024 1:45pm
    unlock ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 22, 2024 1:45pm

    @codiumai-pr-agent-free codiumai-pr-agent-free bot added enhancement New feature or request other labels Apr 4, 2024
    Copy link

    PR Description updated to latest commit (1ef0fdb)

    Copy link

    PR Review

    ⏱️ Estimated effort to review [1-5]

    4, because the PR introduces a significant amount of new functionality, including enhancements and refactoring of existing code. The changes span across multiple files and include both backend and frontend modifications. The complexity of the changes, especially those related to blockchain interactions and the deployment of smart contracts, requires a thorough review to ensure correctness, security, and performance. Additionally, the introduction of new tests and the modification of existing ones indicate the need for careful evaluation of the test coverage and effectiveness.

    🧪 Relevant tests

    Yes

    🔍 Possible issues

    Possible Bug: The error handling in the deployEventPassCollection and deployAPack methods might not cover all failure scenarios, potentially leading to unhandled exceptions.

    Performance Concern: The getSelectedNftsFromPack method involves multiple asynchronous operations within a loop, which could lead to performance issues if not properly managed.

    Security Concern: The handling of secrets and private keys in the deployment process must be reviewed to ensure that sensitive information is not exposed or mishandled.

    🔒 Security concerns

    Sensitive information exposure: The PR involves operations related to smart contract deployment and interaction with blockchain networks. It is crucial to ensure that private keys, secrets, and other sensitive information are securely handled and not exposed in logs, error messages, or through improper API responses.


    ✨ Review tool usage guide:

    Overview:
    The review tool scans the PR code changes, and generates a PR review which includes several types of feedbacks, such as possible PR issues, security threats and relevant test in the PR. More feedbacks can be added by configuring the tool.

    The tool can be triggered automatically every time a new PR is opened, or can be invoked manually by commenting on any PR.

    • When commenting, to edit configurations related to the review tool (pr_reviewer section), use the following template:
    /review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=...
    
    [pr_reviewer]
    some_config1=...
    some_config2=...
    

    See the review usage page for a comprehensive guide on using this tool.

    Copy link

    PR Code Suggestions

    CategorySuggestions                                                                                                                                                       
    Enhancement
    Improve error message clarity in the CollectionDeploymentError constructor.

    Consider using a more descriptive error message that includes the type of event pass when
    deployment fails. This will help in debugging and understanding the context of the error
    more clearly.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts [51]

    -super(`Error deploying an event pass: ${error.message}`);
    +super(`Error deploying an event pass of type ${type}: ${error.message}`);
     
    Add detailed error logging in the catch block of deployEventPassCollection.

    For better error handling, consider logging the error details when catching exceptions in
    the deployEventPassCollection method. This can aid in debugging by providing more context
    about the failure.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts [110]

    -} else console.error(error);
    +} else {
    +  console.error('Failed to deploy event pass collection:', error);
    +}
     
    Use a string enum for the currency field in passPricing for better readability.

    For the currency field in passPricing, consider using a string enum instead of
    Types.Currency_Enum. This would make the code more self-contained and readable, especially
    if the currency codes follow standard ISO currency codes.

    libs/gql/user/types/src/generated/index.ts [148]

    -passPricing?: { __typename?: 'passPricing', amount: number, currency: Types.Currency_Enum } | null
    +passPricing?: { __typename?: 'passPricing', amount: number, currency: 'USD' | 'EUR' | 'GBP' } | null
     
    Best practice
    Use template literals for safer string conversion of chainId.

    To ensure the chainId is always a string as expected by your application logic, consider
    using template literals or the String() function for conversion instead of calling
    toString() directly on chainIdNumber. This approach is more robust and can handle null or
    undefined values without throwing an error.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts [71]

    -const chainId = chainIdNumber.toString();
    +const chainId = `${chainIdNumber}`;
     
    Use a custom error class for missing eventPassDelayedRevealed.

    Instead of using a generic Error for missing eventPassDelayedRevealed, define a custom
    error class that extends Error. This allows for more specific error handling and makes the
    codebase more consistent with other custom errors like CollectionDeploymentError.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts [354]

    -throw new Error('Missing eventPassDelayedRevealed');
    +throw new MissingEventPassDelayedRevealedError();
     
    Validate encryptedIntegritySecret before decryption to prevent errors.

    Consider validating the encryptedIntegritySecret before attempting to decrypt it. This
    validation can prevent potential errors or unexpected behavior when the secret is
    undefined or not in the expected format.

    libs/integrations/external-api-handlers/src/lib/shopify.spec.ts [57]

    +if (!encryptedIntegritySecret) {
    +  throw new Error('encryptedIntegritySecret is required');
    +}
     (decryptSecret as jest.Mock).mockReturnValue('decryptedSecret');
     
    Use a date library for robust and readable time comparisons.

    To ensure the robustness of your timestamp validation, consider using a library like
    moment.js or date-fns to handle time comparisons. This can make the code more readable and
    prevent potential bugs related to time calculations.

    libs/integrations/external-api-handlers/src/lib/shopify.spec.ts [38]

    -timestamp: (Date.now() - 10).toString(), // recent timestamp
    +timestamp: moment().subtract(10, 'seconds').toString(), // Using moment.js for time manipulation
     
    Add detailed error logging for asynchronous operations to aid in debugging.

    When handling errors, especially in asynchronous operations like
    mintLoyaltyCardWithPassword, it's important to provide detailed error logging. This can
    help in diagnosing issues faster and more accurately in production environments.

    libs/integrations/external-api-handlers/src/lib/shopify.spec.ts [297-298]

     mockLoyaltyCardSdk.mintWithPassword.mockRejectedValue(
       new Error('Unexpected error'),
    -);
    +).catch(error => console.error('Error minting loyalty card:', error));
     
    Replace any type with a more specific type for tokenId in EventPassNftFieldsFragment.

    Consider explicitly typing the tokenId field in EventPassNftFieldsFragment and other
    related fragments to improve type safety and clarity. Using any can lead to potential bugs
    and makes the code harder to understand. If the token ID is a numeric value, you might use
    number or string if it's alphanumeric.

    libs/gql/user/types/src/generated/index.ts [150]

    -export type EventPassNftFieldsFragment = { __typename?: 'eventPassNft', tokenId?: any | null, eventId: string, eventPassId: string, organizerId: string, isRevealed: boolean, currentOwnerAddress?: string | null };
    +export type EventPassNftFieldsFragment = { __typename?: 'eventPassNft', tokenId?: string | null, eventId: string, eventPassId: string, organizerId: string, isRevealed: boolean, currentOwnerAddress?: string | null };
     
    Use specific types for dateStart and dateEnd fields instead of any.

    For the dateStart and dateEnd fields within eventDateLocation, consider using a more
    specific type than any. If these fields represent dates, using Date or a string type
    formatted as a date would enhance type safety and code readability.

    libs/gql/user/types/src/generated/index.ts [148]

    -eventDateLocation?: { __typename?: 'EventDateLocation', dateStart: any, dateEnd: any, locationAddress: { __typename?: 'LocationAddress', city: string, country: string, placeId?: string | null, postalCode: string, state?: string | null, street?: string | null, venue?: string | null, coordinates: { __typename?: 'Location', latitude: number, longitude: number } } } | null
    +eventDateLocation?: { __typename?: 'EventDateLocation', dateStart: string, dateEnd: string, locationAddress: { __typename?: 'LocationAddress', city: string, country: string, placeId?: string | null, postalCode: string, state?: string | null, street?: string | null, venue?: string | null, coordinates: { __typename?: 'Location', latitude: number, longitude: number } } } | null
     
    Ensure consistent handling of the isRevealed field across the application.

    The isRevealed field is present in multiple fragments with a boolean type. Ensure that the
    default value or handling of this field is consistent across the application, especially
    in cases where the data might be undefined or null.

    libs/gql/user/types/src/generated/index.ts [150]

    -isRevealed: boolean
    +isRevealed: boolean // Ensure consistent handling of this field across the application
     
    Add assertions for mock function calls to ensure they are used correctly.

    To ensure the robustness of your tests, consider adding assertions for the mock functions'
    calls and parameters. This ensures that your mocks are being used as expected within your
    functions.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts [17-24]

    +const mockCreateWebhooksForEvent = jest.fn().mockResolvedValue({
    +  activityWebhook: {
    +    id: 'mocked_webhook_id',
    +    signingKey: 'mocked_signing_key',
    +  },
    +});
     jest.mock('@features/back-office/events-api', () => ({
       ...jest.requireActual('@features/back-office/events-api'),
    -  createWebhooksForEvent: jest.fn().mockResolvedValue({
    -    activityWebhook: {
    -      id: 'mocked_webhook_id',
    -      signingKey: 'mocked_signing_key',
    -    },
    -  }),
    +  createWebhooksForEvent: mockCreateWebhooksForEvent,
     }));
    +// Later in your tests
    +expect(mockCreateWebhooksForEvent).toHaveBeenCalledWith(expectedArguments);
     
    Use specific types instead of any for better type safety.

    Instead of using any for the type of mockContract, consider defining a more specific
    interface or type. This will improve type safety and make the code more maintainable by
    providing clearer expectations of the object's structure.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts [373]

    -let mockContract: any;
    +interface MockContract {
    +  // Define the expected properties and methods here
    +}
    +let mockContract: MockContract;
     
    Add custom error messages to test assertions for clearer debugging.

    For better error handling and debugging, consider adding custom error messages to the
    expect().toThrow() assertions in your tests. This will help identify which test case fails
    more quickly if the expected error is not thrown.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts [297-313]

     await expect(
       eventPassCollection.deployEventPassCollection(
         event.eventPasses[0],
         {
           eventId: event.id,
           organizerId: eventPassOrganizerId,
           contractType: EventPassNftContractType_Enum.Normal,
         },
       ),
     ).rejects.toThrow(
       new CollectionDeploymentError(
         new Error(
           'Error deploying a normal collection : Error deploying a drop contract : Error in deployBuiltInContract',
         ),
       ),
    -);
    +).withErrorMessage('Expected CollectionDeploymentError was not thrown for normal collection deployment');
     
    Maintainability
    Extract external URL generation into a separate function.

    To improve code maintainability and readability, consider extracting the logic for
    generating external_url into a separate function. This will make it easier to modify the
    URL structure in the future and keeps the code DRY.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.ts [125]

    -external_url: `${EVENT_PASS_BASE_URL}${organizerId}/event/${eventId}/eventPass/${eventPassId}/${i}`,
    +external_url: generateExternalUrl(organizerId, eventId, eventPassId, i),
     
    Use dependency injection for the LoyaltyCardNftWrapper to improve test flexibility.

    Instead of directly mocking LoyaltyCardNftWrapper with a jest mock, consider using
    dependency injection to pass a mock or a real instance. This approach enhances the test's
    flexibility and maintainability by decoupling the test setup from the implementation
    details.

    libs/integrations/external-api-handlers/src/lib/shopify.spec.ts [12-16]

    -jest.mock('@nft/loyalty-card', () => ({
    -  LoyaltyCardNftWrapper: jest.fn().mockImplementation(() => ({
    -    mintWithPassword: jest.fn(),
    -  })),
    -}));
    +// In the constructor of ShopifyWebhookAndApiHandler or as a method parameter
    +constructor(private loyaltyCardNftWrapper: LoyaltyCardNftWrapper = new LoyaltyCardNftWrapper()) {}
    +// In tests
    +const mockLoyaltyCardNftWrapper = { mintWithPassword: jest.fn() };
    +const handler = new ShopifyWebhookAndApiHandler(mockLoyaltyCardNftWrapper);
     
    Abstract common setup logic into a separate function or beforeEach block for better readability.

    To improve the readability and maintainability of the test cases, consider abstracting the
    common setup logic into a separate function or before each block. This includes mocking
    return values and creating common objects like mockRequest.

    libs/integrations/external-api-handlers/src/lib/shopify.spec.ts [50-55]

    -(getSecretApiKey as jest.Mock).mockResolvedValue({
    -  type: ApiKeyType_Enum.Shopify,
    -  encryptedIntegritySecret: 'encryptedSecret',
    -  allowlist: 'https://example.myshopify.com',
    -  organizerId: 'org123',
    +beforeEach(() => {
    +  (getSecretApiKey as jest.Mock).mockResolvedValue({
    +    type: ApiKeyType_Enum.Shopify,
    +    encryptedIntegritySecret: 'encryptedSecret',
    +    allowlist: 'https://example.myshopify.com',
    +    organizerId: 'org123',
    +  });
    +  // Other common setup logic
     });
     
    Rename the passPricing type to PassPricing for consistency.

    The passPricing field's type is passPricing, which seems inconsistent with the naming
    convention used for other types (e.g., EventPass, Asset). Consider renaming passPricing to
    PassPricing to maintain consistency and improve readability.

    libs/gql/user/types/src/generated/index.ts [148]

    -passPricing?: { __typename?: 'passPricing', amount: number, currency: Types.Currency_Enum } | null
    +passPricing?: { __typename?: 'PassPricing', amount: number, currency: Types.Currency_Enum } | null
     
    Improve variable naming for better readability.

    Consider using a more descriptive variable name instead of mockContract to improve code
    readability. For instance, if this mock contract is simulating a specific type of
    contract, naming it accordingly can make the tests easier to understand.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts [373]

    -let mockContract: any;
    +let mockEventPassContract: any;
     
    Extract mock setup to a separate function for clarity.

    To improve the test's clarity and maintainability, consider extracting the setup of mocked
    values and instances (like mockedThirdwebSDKInstance and mockContract) into a separate
    function or before each block. This helps in reusing setup code and keeping individual
    tests focused and concise.

    libs/nft/thirdweb-organizer-event-pass/src/lib/index.integration.test.ts [372-373]

     let mockedThirdwebSDKInstance: ThirdwebSDK;
     let mockContract: any;
    +beforeEach(() => {
    +  // Setup mockedThirdwebSDKInstance and mockContract here
    +});
     

    ✨ Improve tool usage guide:

    Overview:
    The improve tool scans the PR code changes, and automatically generates suggestions for improving the PR code. The tool can be triggered automatically every time a new PR is opened, or can be invoked manually by commenting on a PR.

    • When commenting, to edit configurations related to the improve tool (pr_code_suggestions section), use the following template:
    /improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=...
    
    [pr_code_suggestions]
    some_config1=...
    some_config2=...
    

    See the improve usage page for a comprehensive guide on using this tool.

    🐛 fix(server.ts): change port variable case from lowercase port to uppercase PORT to improve semantics
    ✨ feat(server.ts): add support for process.env.PORT environment variable to be able to run app on a configurable port
    🔥 chore: delete down.sql and up.sql files for inserting and deleting 'loyalty_card' value from eventPassNftContractType table
    🔧 chore(project.json): fix typo in project name from 'features-back-office-eventss' to 'features-back-office-events'
    ✨ feat(deployEventPassCollectionWrapper.ts): add new action to deploy event pass collection
    ✨ feat(revealEventPassDelayedContract.ts): add new action to reveal event pass delayed contract
    🔧 chore(EventPassCardFooter.tsx): fix import statement for revealEventPassDelayedContract action
    🔧 chore(EventPassDeployButtonClient.tsx): fix import statement for deployEventPassCollectionWrapper action
    🔧 chore(EventPassNftFilesTable/examples.tsx): fix import statements for deployEventPassCollectionWrapper and revealEventPassDelayedContract actions
    🔧 chore(EventSheet.stories.tsx): fix import statements for deployEventPassCollectionWrapper and revealEventPassDelayedContract actions
    🔧 chore(action.ts): fix error message to include optional chaining for user.kyc
    🔧 chore(index.spec.ts): fix describe block name for deployEventPassCollection
    🔧 chore(index.ts): fix BASE_URL variable name to EVENT_PASS_BASE_URL
    🔧 chore(nftCollection.integration.test.ts): fix describe block name for deployEventPassCollection and revealEventPassDelayedContract
    ✨ feat(nftCollection.integration.test.ts): add tests for error cases in deployEventPassCollection and revealEventPassDelayedContract
    
    🔧 chore(next.config.js): remove unused 'useDeploymentId' and 'useDeploymentIdServerActions' options
    📦 chore(package.json): update 'next' and 'eslint-config-next' dependencies to version 14.1.4
    
    🔄 refactor(index.ts): rename CommonProps interface to EventPassCommonProps for better clarity and semantics
    🔄 refactor(index.ts): rename props parameter in several methods to EventPassCommonProps for better clarity and semantics
    🔄 refactor(index.ts): change return type of getEventPassCommonProps and validateEventPassDeployInputs methods to EventPassCommonProps for better clarity and semantics
    🔄 refactor(index.ts): change parameter type of deployEventPassDropContractAndPrepareMetadata and deployAnEventPassNftDropCollection methods to EventPassCommonProps for better clarity and semantics
    🔄 refactor(index.ts): change parameter type of deployEventPassDelayedRevealCollection and deployLoyaltyCardCollection methods to EventPassCommonProps for better clarity and semantics
    
    📝 chore(loyaltyCardNftContract): add loyaltyCardNftContract table to the database schema
    
    📝 chore(loyaltyCardNftContract): create up.sql and down.sql migration files for loyaltyCardNftContract table
    
    📝 chore(loyaltyCardNftContract): add loyaltyCardNftContract table definition and comments
    
    📝 chore(loyaltyCardNftContract): add trigger to set updated_at column on updates
    
    📝 chore(loyaltyCardNftContract): add function to force lowercase contractAddress, loyaltyCardId, and activityWebhookId
    
    📝 chore(loyaltyCardNftContract): add trigger to apply lowercase function before insert
    
    📦 chore(loyaltyCardNft): add loyaltyCardNft table and its remote relationships to improve loyalty card functionality
    📦 chore(loyaltyCardNftContract): add loyaltyCardNftContract table and its remote relationships to improve loyalty card functionality
    📦 chore(tables.yaml): include public_loyaltyCardNft.yaml in tables.yaml to enable loyaltyCardNft table
    📦 chore(1710944716876_loyaltyCardNft): add up.sql and down.sql files to create loyaltyCardNft table and its triggers and comments
    
    packNftSupply
    
    🚀 feat(migrations): add migration files for updating Stamps and LoyaltyCards
    
    📝 Add down.sql file:
    - The down.sql file contains the necessary SQL statements to revert the changes made in the corresponding up.sql file.
    - It includes:
      - Adding the "stampNftId" column to the "nftTransfer" table.
      - Adding the "stampAmount" column to the "nftTransfer" table.
      - Adding a foreign key constraint for the "stampNftId" column in the "nftTransfer" table.
      - Adding comments for the new columns in the "nftTransfer" table.
      - Dropping the existing check constraint in the "nftTransfer" table.
      - Adding the updated check constraint in the "nftTransfer" table.
      - Adding the "campaignId" and "loyaltyCardId" columns to the "minterTemporaryWallet" table.
      - Adding comments for the new columns in the "minterTemporaryWallet" table.
    
    📝 Add up.sql file:
    - The up.sql file contains the necessary SQL statements to apply the changes to the database.
    - It includes the same SQL statements as the down.sql file, which are:
      - Adding the "stampNftId" column to the "nftTransfer" table.
      - Adding the "stampAmount" column to the "nftTransfer" table.
      - Adding a foreign key constraint for the "stampNftId" column in the "nftTransfer" table.
      - Adding comments for the new columns in the "nftTransfer" table.
      - Dropping the existing check constraint in the "nftTransfer" table.
      - Adding the updated check constraint in the "nftTransfer" table.
      - Adding the "campaignId" and "loyaltyCardId" columns to the "minterTemporaryWallet" table.
      - Adding comments for the new columns in the "minterTemporaryWallet" table.
    
    🐛 fix(deployEventPassCollectionWrapper.ts): change import statement from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(revealEventPassDelayedContract.ts): change import statement from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(index.spec.ts): change import statement from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(index.ts): change class name from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(nftCollection.integration.test.ts): change import statement from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(nftCollection.integration.test.ts): change describe block title from NftCollection to EventPassCollection to reflect correct class name
    🐛 fix(packCollection.integration.test.ts): change describe block title from PackCollection to EventPassCollection to reflect correct class name
    🐛 fix(packCollection.integration.test.ts): change comment to reflect correct class name
    ✨ feat(deployEventPassCollectionWrapper.ts): add support for deploying event pass collections using the EventPassCollection class
    ✨ feat(revealEventPassDelayedContract.ts): add support for revealing event pass delayed contracts using the EventPassCollection class
    ✨ feat(index.spec.ts): add tests for the EventPassCollection class
    ✨ feat(index.ts): create EventPassCollection class to handle event pass collections
    ✨ feat(nftCollection.integration.test.ts): add integration tests for the EventPassCollection class
    ✨ feat(nftCollection.integration.test.ts): add tests for deploying event pass collections using the EventPassCollection class
    ✨ feat(packCollection.integration.test.ts): add integration tests for the EventPassCollection class
    
    📝 chore(loyaltyCardNftContract.yaml): add loyaltyCardParameter object relationship using foreign_key_constraint_on to improve data integrity
    
    📝 chore(loyaltyCardParameters.yaml): create loyaltyCardParameters table to store properties of loyalty cards and establish a relationship with loyaltyCardNftContract table
    
    📝 chore(loyaltyCardStatus.yaml): create loyaltyCardStatus table as an enum to represent the status of loyalty cards
    
    📝 chore(tables.yaml): include public_loyaltyCardParameters.yaml and public_loyaltyCardStatus.yaml in the list of tables
    
    📝 chore(remote_schemas.yaml): add relationships between loyaltyCard and loyaltyCardNftContract, loyaltyCardParameters to enable querying related data
    
    📝 chore(1710936959258_loyaltyCardNftContract/down.sql): remove down migration for loyaltyCardNftContract table
    
    📝 chore(1710936959258_loyaltyCardNftContract/up.sql): create loyaltyCardStatus table, loyaltyCardParameters table, and establish a relationship between loyaltyCardNftContract and loyaltyCardParameters tables
    
    📝 chore(loyaltyCard.query.gql): add query to fetch loyalty card parameters for a specific organizer and stage
    
    📦 chore(database): add new tables for Shopify campaign parameters and status
    📄 feat(database): create YAML files for new tables public_shopifyCampaignParameters and public_shopifyCampaignStatus
    📄 feat(database): add new tables public_shopifyCampaignParameters and public_shopifyCampaignStatus to tables.yaml
    🔧 fix(database): add SQL scripts to create and modify tables for Shopify campaign parameters and status
    
    📦 chore(loyalty-card-types): add new library for managing loyalty card types in the back office
    
    📝 docs(loyalty-card-types): add README.md file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add package.json file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add project.json file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add tsconfig.json file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add tsconfig.lib.json file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add index.ts file for the loyalty-card-types library
    
    🔧 chore(loyalty-card-types): add lib/index.ts file for the loyalty-card-types library
    
    moved nft-thirdweb-organizer to nft-thirdweb-organizer-event-pass
    
    remove pack from nft-thirdweb-organizer-event-pass lib and move to new library nft-thirdweb-organizer-pack
    
    moved the actions from event-pass to pack library
    
    moved loyalty-card from event-pass lib to own library
    
    new stamps library
    
    fix build for nft-thirdweb-organizer-event-pass
    
    ✨ Add new library `nft-thirdweb-organizer-common` with ESLint, SWC config, README, Jest setup, and initial TypeScript implementation
    
    ♻️ Refactor `thirdweb-organizer-event-pass` to use common functionality
    
    - Removed `insertMinterTemporaryWallet` function and related types to centralize logic in `thirdweb-organizer-common` module.
    - Updated error message in `CollectionDeploymentError` to reflect the correct deployment type (`event pass` instead of `collection`).
    - Introduced `ThirdwebOrganizerCommon` class to handle common functionalities like getting address and chain ID, and setting ERC721 contract with claim conditions, which simplifies the `EventPassCollection` class by removing redundant code.
    - Adjusted test error message to match the updated error handling in deployment.
    - Added `@nft/thirdweb-organizer-common` path in `tsconfig.base.json` to support the new common module import.
    
    This refactor aims to reduce code duplication and improve maintainability by centralizing common functionalities used across different parts of the `thirdweb-organizer-event-pass` module.
    
    ✨ (Hasura metadata & migrations): Add `nftMintPassword` table for NFT minting authentication
    
    - **Why?** To securely manage unique passwords for NFT minting, ensuring each password is linked to a specific contract, chain ID, and organizer. This facilitates controlled access to NFT minting operations.
    
    ♻️ Move minterTemporaryWallet mutation from event/pass to organizer/nft
    ✨ Add loyaltyCardId and campaignId fields to minterTemporaryWallet mutation
    ✨ Create query for minterTemporaryWallet by eventPassId in organizer/nft
    
    ✨ (nftMintPassword schema): Rename `ownerAddress` to `minterAddress` to better reflect its purpose
    📝 Update comments and function logic to align with `minterAddress` field change
    ✨ (GraphQL): Add queries and mutations for managing NFT mint passwords
    ✨ (thirdweb-organizer-common): Add functions to insert and retrieve NFT mint passwords
    
    ✨ (index.ts): Implement loyalty card collection deployment and management
    
    - Add imports for necessary modules and interfaces to support loyalty card functionalities.
    - Introduce `LoyaltyCardCollection` class with methods to deploy loyalty card collections and manage their properties.
    - Implement error handling specific to loyalty card collection deployment through `CollectionDeploymentError`.
    - Enhance class with methods for retrieving common properties and deploying contracts with metadata preparation.
    
    ✨ (crypto lib): add `generateRandomAlphanumericString` function for secure random string generation
    ✅ (crypto tests): add tests for `generateRandomAlphanumericString` to ensure functionality and randomness
    ✨ (nft lib): integrate `generateRandomAlphanumericString` for NFT mint password generation
    
    ✨ (loyalttCard.mutation.gql, loyaltyCard.query.gql, nftMintPassword.mutation.gql): add new GraphQL mutations and queries for loyalty card and NFT minting
    ♻️ (action.ts, index.ts): refactor NFT and loyalty card logic to improve structure and readability
    🔧 (index.ts): add logic to deploy loyalty card contracts with claim conditions and create NFT mint passwords
    
    ✨ (index.integration.test.ts): add integration tests for NFT event pass deployment
    
    ✨ Add tests for delayed reveal functionality in EventPassCollection
    
    This commit introduces unit tests for the `revealEventPassDelayedContract` method within the `EventPassCollection` class. The tests cover scenarios including successful reveal and update of the delayed reveal status, handling errors during the reveal process, and errors updating the reveal status in the database. These tests ensure the robustness and reliability of the delayed reveal feature, facilitating a smoother user experience and reducing potential issues in the reveal process.
    
    ✨ Export `CollectionDeploymentError` class for broader error handling
    ✅ Add tests for `LoyaltyCardCollection` to ensure functionality and error handling
    ♻️ Refactor `deployLoyaltyCardCollection` method in `LoyaltyCardCollection` for clarity and efficiency
    
    ⬆️ Update Hasura version from v2.35.0 to v2.38.0 across project configurations
    
    ✨ (15_minterTemporaryWallet.sql): extend minterTemporaryWallet table with new columns for loyaltyCardId and campaignId to support broader use cases
    ✨ (16_loyaltyCardParameters.sql, 17_loyaltyCardNftContract.sql, 18_loyaltyCardNft.sql, 19_nftMintPassword.sql, 20_shopifyCampaignParameters.sql, 21_stampNftContract.sql, 22_stampNft.sql, 23_stampNftSupply.sql): add new seed files for loyalty card parameters, NFT contracts, mint passwords, Shopify campaign parameters, and stamp NFTs to setup initial data structure for loyalty program and campaign management
    
    ✨ (index.integration.test.ts): add integration tests for LoyaltyCardCollection deployment
    📝 (db/src/index.ts, deleteAllData.js): update database utilities and scripts to support loyalty card features
    
    ✨ (gql/admin/api): add queries for fetching minter temporary wallet by loyaltyCardId and campaignId
    ✅ (nft/thirdweb-organizer-loyalty-card): add integration test to verify fetching minter temporary wallet by loyaltyCardId
    
    ✨ (loyaltyCard.query.gql): Add query to fetch loyalty card NFT contract by ID
    ♻️ (index.integration.test.ts): Refactor mockSigner to use 'mockUserAddress' for clarity
    ✨ (index.integration.test.ts): Implement test for fetching NFT mint passwords and loyalty card contract address
    
    ♻️ (createNftActivityWebhookForEvent.ts): refactor method name for clarity and consistency
    ✨ (index.spec.ts, index.ts): add createNftMetadataUpdateWebhook functionality to support NFT metadata updates
    ♻️ (index.spec.ts, index.ts): rename deleteNftActivityWebhook to deleteWebhook for generalization
    📝 (index.ts): add documentation link for NFT metadata updates webhook
    
    ✨ Add loyalty-card-api library with ESLint, SWC config, and Jest setup
    
    ✨ (GraphQL): Add CreateLoyaltyCardParameters mutation for loyalty card parameters insertion
    ✨ (GraphQL): Add GetAlchemyInfosFromLoyaltyCardId query to fetch loyalty card parameters
    ✨ (Action.ts): Introduce LoyaltyCardParameters_Insert_Input import and createLoyaltyCardParametersAndWebhook function for webhook creation
    ✨ (Index.ts): Implement saveLoyaltyCardContractIntoDb to save contract details and create webhook
    🔧 (tsconfig.base.json): Update paths to include @features/loyalty-card-api for better module resolution
    
    ✨ (route.ts): Add new webhook route for passing NFT activity by eventId
    ✨ (up.sql): Introduce activity and metadata webhook signing keys in loyaltyCardParameters and shopifyCampaignParameters tables for enhanced security
    ♻️ (down.sql): Refactor nftMintPassword table comments for clarity and consistency
    ♻️ (up.sql): Rename signingKey to activityWebhookSigningKey in lotteryParameters and eventParameters tables for better specificity
    ✨ (up.sql): Add metadataUpdateWebhookId and metadataUpdateWebhookSigningKey columns to eventParameters table to support metadata updates
    
    ✨ (hasura migrations): Add `nftMintPassword` table with improved formatting and comments for clarity
    ♻️ (hasura migrations): Refactor trigger and function creation for consistency
    ✨ (hasura migrations): Rename `signingKey` to `activityWebhookSigningKey` and add `metadataUpdateWebhookId` and `metadataUpdateWebhookSigningKey` columns to support new webhook functionality
    📝 (SQL comments): Update comments to reflect changes and add new comments for clarity
    ✨ (libs): Update webhook URL paths and query fields to support new and renamed webhook functionalities
    ♻️ (libs): Refactor webhook signature validation to use new `activityWebhookSigningKey` field
    🐛 (libs): Fix incorrect usage of `use server` directive in TypeScript files
    
    ✨ (index.integration.test.ts): Rename `signingKey` to `activityWebhookSigningKey` for clarity
    ♻️ (action.ts): Refactor loyalty card action to include webhook creation logic
    📝 (action.ts): Add 'use server' directive for strict mode enforcement
    
    ✨ (SQL Migrations & Seeds): Make `loyaltyCardId` unique and update seed data structure
    - Why: Ensuring `loyaltyCardId` is unique across the database enhances data integrity and prevents duplicate entries. Updating the seed data structure aligns with the new database schema and prepares for new webhook functionalities.
    
    ✨ (Loyalty Card API): Enhance webhook creation and update logic
    - Why: Introducing optional parameters for creating and updating webhooks allows for more flexible and efficient webhook management. This change supports scenarios where only specific types of webhooks need to be created or updated, reducing unnecessary operations and improving performance.
    
    🔧 (TS Config): Add "next" to types in tsconfig.lib.json
    - Why: Including "next" in the compiler options ensures proper type checking and IntelliSense for Next.js features within the loyalty card API library, improving developer experience and code quality.
    
    ♻️ refactor(pass-api): generalize NFT webhook functions for broader use
    ✨ feat(pass-api): add tests for create and update webhook functions
    ✨ feat(gql/admin/api): add loyalty card mutations and update queries
    
    ♻️ Refactor webhook function names and logic for clarity and consistency
    ✨ Add support for metadata update webhooks in loyalty card and event pass modules
    💡 Update comments and logs for better understanding of webhook handling process
    
    ♻️ (action.ts): refactor webhook ID assignments to handle potentially undefined IDs more gracefully in both event pass and loyalty card modules
    
    ✨ (events-api): add createWebhooksForEvent and getAlchemyInfosFromEventId exports
    ✨ (events-api): add createWebhooksForEvent and updateWebhooksForEvent functionality
    ✅ (events-api): add tests for createWebhooksForEvent and updateWebhooksForEvent
    ♻️ (various): update imports to reflect new location of createWebhooksForEvent and getAlchemyInfosFromEventId
    🔧 (nftActivity): update import path for getAlchemyInfosFromEventId to reflect new module location
    
    ✨ Add loyalty-card-api library with ESLint, SWC config, README, Jest setup, and initial implementation
    
    - 📝 Add README.md for documentation on building and testing the library
    - 🔧 Add .eslintrc.json for ESLint configuration extending project-wide rules
    - 🔧 Add .swcrc for SWC compiler configuration targeting ES2017 and enabling decorators
    - ✅ Add jest.config.ts for Jest testing framework setup, utilizing SWC for transformation
    - 📦 Add package.json defining the library name, version, dependencies, and main entry points
    - 🚀 Add project.json for Nx project configuration, specifying build, lint, and test targets
    - ✨ Add initial TypeScript implementation for loyalty card API features, including creating and updating webhooks and fetching Alchemy information based on loyalty card ID
    - ⬆️ Add tsconfig.json and tsconfig.lib.json for TypeScript compiler options and library-specific settings
    
    ✨ Add tsconfig.spec.json for loyalty-card-api to support Jest testing
    ♻️ Refactor loyalty-card-api exports to use a single dummy export for simplification
    🔧 Update import paths in thirdweb-organizer-loyalty-card to reflect loyalty-card-api's new location and structure
    ✅ Update jest.mock paths in thirdweb-organizer-loyalty-card integration tests to align with loyalty-card-api's new location
    
    ✨ (main.ts): add createDate to test role assignment for better tracking
    ♻️ (main.ts): normalize address input to lowercase for consistency
    ✨ (index.ts, siweProvider.ts): exclude 'fake-' prefixed applicantIds to differentiate test accounts from real ones
    
    ♻️ Refactor cache key generation to async across multiple modules for consistency and future flexibility
    
    ✨ Introduce loyalty card feature in back-office app
    
    - Add loyalty card loading and page components for localized support
    - Implement loyalty card feature in back-office navigation
    - Setup ESLint configuration, README, Jest config, and package.json for loyalty card library
    - Configure TypeScript for loyalty card library development and testing
    
    ✨ (i18n/en.json): add "Loyalty Card" and "Shopify Campaigns" to English locales
    ✨ (icons.tsx): introduce Shopify and Loyalty Card icons for UI enhancement
    🔧 (tsconfig.base.json): update tsconfig paths for loyalty card features integration
    
    ✨ (loyalty-card/page.tsx): add async fetching of loyalty card parameters
    ♻️ (events-api, loyalty-card-api): refactor imports and update functions to inject dependencies
    ✅ (loyalty-card-api): add tests for createWebhooksForLoyaltyCard and getLoyaltyCardParameters
    📝 (loyalty-card-api): export getLoyaltyCardParameters function for external use
    
    ✨ Add `getLoyaltyCardParameters` function to fetch loyalty card details based on user role and environment stage
    
    ♻️ Update `LoyaltyCardPage` to accept `loyaltyCard` prop for dynamic content rendering
    
    🔧 Adjust TypeScript config to allow property access from index signature by setting `noPropertyAccessFromIndexSignature` to false
    
    ♻️ Refactor GraphQL query `GetLoyaltyCardParametersOrganizer` to use `organizerId` for clarity and consistency
    
    💡 Update class names in `DrawerDemo` for consistency in button sizing
    
    ♻️ Refactor loyalty card API to use `getLoyaltyCardOrganizer` for clarity
    ✨ Add `getLoyaltyCardOrganizer.spec.ts` for testing new API functionality
    📝 Update GraphQL query to include `loyaltyCardNftContract` data
    ✅ Add tests to ensure correct behavior of `getLoyaltyCardOrganizer`
    
    ✨ (loyalty-card-api & loyalty-card): Add NFT mint password retrieval and display functionality
    
    - Added `getNftMintPasswordsForContract` function to fetch NFT mint passwords based on contract address and chain ID.
    - Introduced new components `LoyaltyCardNftsInfos`, `LoyaltyCardNftsPasswords`, and `LoyaltyCardNftsPasswordsTable` to display NFT information and mint passwords in the loyalty card section.
    - Enhanced user experience by providing detailed NFT information and access to mint passwords directly from the loyalty card interface.
    
    ✨ (LoyaltyCardNftsPasswordsTableClient.tsx, examples.tsx, LoyaltyCardPage.stories.tsx): add new components and stories for LoyaltyCardNftsPasswordsTable to enhance back-office functionality with NFT password management
    
    ✨ (LoyaltyCardPage.tsx): Refactor LoyaltyCardPage to include Accordion UI for NFT info and passwords
    ✨ (examples.tsx): Add examples file for LoyaltyCardPage component showcasing usage
    ✨ (loyaltyCard.query.gql, nftMintPassword.query.gql): Extend GraphQL queries to include chainId and password metadata
    📝 (en.json): Update English localization messages for LoyaltyCardPage components
    ♻️ (index.ts): Refactor NFT types to include NftMintPasswordOrganizer type
    
    ✨ Introduce loyalty card feature with deployment and reset actions
    ♻️ Refactor deployEventPassCollection to use return statement for consistency
    ✨ Add LoyaltyCardFooter component for managing loyalty card deployment UI
    ✨ Implement LoyaltyCardDeployButtonClient for initiating loyalty card deployment
    ✨ Create resetLoyaltyCard action to revalidate loyalty card paths
    ♻️ Change className from "max-w-fit" to "min-w-fit" in LoyaltyCardNftsPasswords for better layout management
    ♻️ Update icon from Download to Copy in LoyaltyCardNftsPasswordsTableClient to reflect actual functionality
    ✨ Add stories for LoyaltyCardPage to showcase different states (Not Deployed, Deployed)
    
    ✨ (LoyaltyCardPage.tsx): Add `AppContainerFooter` and `LoyaltyCardFooter` to enhance UI
    ♻️ (Various files): Refactor to automatically include `organizerId` in NFT actions, improving DX
    📝 (en.json): Update and add localization strings for loyalty card features
    🐛 (en.json): Fix typo in error message for contract deployment
    ⬆️ (tsconfig.lib.json): Include types directory to improve type checking
    💡 (Various files): Add comments and refactor types for clarity and maintainability
    
    ✨ (EventPassDeployButtonClient.tsx): remove TODO comment as deploy button implementation is complete
    ♻️ (LoyaltyCardFooter.tsx): refactor div class to use flex for better alignment
    ✨ (examples.tsx): add examples file for LoyaltyCardFooter with mocks for storybook
    📝 (LoyaltyCardPage.stories.tsx): update stories to include new mocks and decorators for better visualization
    🚀 (LoyaltyCardPage.stories.tsx): update contract address in 'Deployed' story for accuracy
    
    🔧 Update chain IDs and API keys for enhanced network compatibility and security
    
    ✨ Add support for Base Sepolia and Polygon Amoy testnets to expand network options
    
    ⬆️ Upgrade dependencies to latest versions for improved functionality and security
    
    ♻️ Refactor code to utilize dynamic chain IDs for increased flexibility in network operations
    
    🔧 (tools/test/.env.test.jest): update chain IDs to '84532' for consistency and to reflect the new test environment configuration
    
    ✨ (middleware.ts): add 'loyalty-card' routes to authPages for access control
    ♻️ (public_loyaltyCardNftContract.yaml): refactor loyaltyCardId relationship to use manual configuration for clarity
    ✨ (ProfileNavClient.tsx): redirect to home page on sign out for better user experience
    ✨ (AddMoreNftsPasswords.tsx): introduce AddMoreNftsPasswords component for managing NFT passwords
    ♻️ (LoyaltyCardNftsPasswordsTableClient.tsx): integrate AddMoreNftsPasswords component and remove early return for consistency
    
    ✨ (ContentSpaceFilesUploader.stories.tsx): streamline imports by consolidating expect function
    ✨ (loyalty-card-api): add resetNftMintPasswordsForContract function to support resetting NFT mint passwords
    ♻️ (getNftMintPasswordsForContract.ts): refactor to include cache tag for revalidation
    ✨ (createNftsPasswords.ts): introduce function to create NFT mint passwords
    🔥 (AddMoreNftsPasswords.tsx): remove unused component
    ✨ (AddMoreNftsPasswordsDrawer.tsx): add new component for adding more NFTs passwords through a UI drawer
    ♻️ (LoyaltyCardNftsPasswordsTable.tsx): update to support new AddMoreNftsPasswordsDrawer component
    
    ✨ (LoyaltyCardNftsPasswordsTableClient.tsx, examples.tsx, LoyaltyCardPage.stories.tsx, en.json, index.ts, DataTableToolbar.tsx): Enhance loyalty card feature with 'One Time Codes' management
    
    - Refactor `AddMoreNftsPasswords` to `AddMoreNftsPasswordsDrawer` for a more intuitive UI.
    - Introduce a new UI element to display when no 'One Time Codes' are available, improving user guidance.
    - Implement storybook interactions to simulate user flows for creating 'One Time Codes'.
    - Update localization files to reflect the terminology change from 'passwords' to ''One Time Codes'', enhancing clarity.
    - Extend `CreateNftMintPasswordsProps` interface to ensure required properties are provided, improving type safety.
    - Add `toolbarChildren` prop to `DataTableToolbar` for flexible toolbar customization.
    
    ♻️ Refactor code for better null safety and async patterns across multiple files
    
    - Ensure null safety with optional chaining in React components
    - Refactor async functions for clarity and remove deprecated cache usage
    - Simplify async data fetching and state management in React components
    - Update ESLint configuration and remove unnecessary dependencies
    - Adopt modern JavaScript practices for server-side code in API utilities
    
    ♻️ Refactor role and organizerId checks to use optional chaining for better code safety and readability across multiple files
    ✨ Add jest mock for getCurrentUser to simulate user context in loyalty card integration tests
    ✨ Include chainId in loyalty card contract test expectation for more comprehensive testing
    
    ✨ (Hasura metadata & migrations): Add `nftStatus` table as enum, update related tables
    
    - Introduced `nftStatus` enum table to standardize NFT status across the database.
    - Updated `eventPassNft` and `packNftSupply` tables to reference `nftStatus`.
    - Created `loyaltyCardNft` table to manage NFTs associated with loyalty cards, including status tracking and unique constraints to ensure data integrity.
    - Implemented triggers and functions to maintain data consistency, such as updating timestamps and enforcing lowercase for specific fields.
    
    ✨ (1710944716876_nftStatus_loyaltyCardNft/up.sql): introduce nftStatus table and loyaltyCardNft table to manage NFT statuses and loyalty card NFTs, respectively, enhancing NFT lifecycle management
    ♻️ (1710944716876_nftStatus_loyaltyCardNft/up.sql): refactor eventPassNft and packNftSupply tables by replacing isDelivered column with status column linked to nftStatus, improving data integrity and status tracking
    🔧 (1710944716876_nftStatus_loyaltyCardNft/up.sql): add triggers and functions for loyaltyCardNft table to ensure data consistency, specifically for contractAddress and ownerAddress fields
    📝 (1710944716876_nftStatus_loyaltyCardNft/up.sql): document tables and columns for clarity and maintainability, focusing on the purpose and relationships of loyaltyCardNft and related entities
    
    ✨ (SQL migration & GraphQL): Add 'HELD_BY_CONTRACT' and 'LAZY_MINTED' statuses to nftStatus table and update queries to support lazy minted NFTs
    
    ♻️ (TypeScript & GraphQL): Refactor NFT handling to support lazy minted NFTs across services and update types accordingly
    
    💡 (TypeScript): Update comments and types to clarify changes and ensure type safety with lazy minted NFTs handling
    
    ✨ (Multiple Files): Integrate `date-fns-tz` for timezone-aware date handling
    
    - **Why?** To ensure that all date and time calculations are correctly adjusted for the timezone, specifically for events and sales in the `Europe/London` timezone. This change addresses potential issues with time-sensitive operations not respecting the intended timezone, leading to inaccuracies in event status evaluations (e.g., whether an event or sale is ongoing).
    
    ✨ (11_eventPassNft.sql): Add 'status' column to eventPassNft table to track NFT minting status
    
    ✨ Add new entries to database for event passes and packs with various statuses
    
    ✨ (packCollection.integration.test.ts): add NftStatus_Enum.LazyMinted to test data to align with updated NFT status requirements
    
    ✨ Add mutations and queries for loyalty card NFT operations
    ✨ Introduce NFT mint password mutations and queries enhancements
    📝 Create nft-loyalty-card library with initial setup and documentation
    🔧 Add ESLint and SWC configurations for nft-loyalty-card library
    🚀 Prepare nft-loyalty-card library for building and testing with Nx, Jest
    
    ✨ (nft/loyalty-card): add LoyaltyCardNftWrapper class and tests for NFT loyalty card management
    🔧 (nft/loyalty-card): add tsconfig for loyalty card library to enforce strict type-checking
    
    ✨ (nft/loyalty-card): add tsconfig files for library and specs
    ✨ (nft/mint-password): add initial setup with ESLint, SWC config, README, Jest config, package.json, and project.json
    ✨ (nft/mint-password): implement index and unit tests for mint password functionality
    
    ✨ (nft/mint-password): add new library for NFT mint password functionality
    🔧 (nft/mint-password): add TypeScript configuration for the new library
    ♻️ (nft/types): update NFT types to include mint password types
    ⬆️ (tsconfig.base.json): update base TypeScript config to include new NFT libraries
    🔧 (nft/thirdweb-admin): remove unnecessary tslib dependency
    
    ✨ Add new route for NFT activity webhook handling
    ♻️ Standardize webhook URL formatting across the application for consistency
    
    ♻️ refactor(crypto): standardize parameter name from 'string' to 'body'
    
    This change improves the clarity and consistency of the parameter names across the crypto library functions, making the codebase more intuitive and easier to understand.
    
    ✨ feat(integrations-external-api-handlers): add new library for external API handlers
    
    This introduces a new library dedicated to handling external API integrations, including configuration files, documentation, and setup for testing and linting. This addition aims to centralize and streamline the management of external API interactions within the project.
    
    ✨ Add BaseWebhookAndApiHandler with tests and TS config for external API handlers
    🐛 Fix parameter name in Kyc and Webhooks utils for consistent signature verification
    🔧 Update tsconfig.base.json to include external-api-handlers path mapping
    
    ✨ (crypto lib): add generateApiKeyId, hashSecret, verifySecret functions
    
    - `generateApiKeyId` for generating unique API key IDs with optional custom prefixes.
    - `hashSecret` and `verifySecret` for securely hashing and verifying secrets using PBKDF2.
    
    ✅ (crypto tests): add tests for new crypto functions
    
    - Tests ensure `generateApiKeyId` produces correctly formatted and unique IDs.
    - Tests for `hashSecret` and `verifySecret` validate correct hashing and verification behavior, including handling of incorrect secrets or salts.
    
    ✨ (Hasura metadata): add new tables for managing Shopify API keys
    📝 (Hasura migrations): create migration scripts for apiKeyStatus, shopifyApiKey, and shopifySecretApiKey tables
    🔧 (Hasura config): update tables.yaml to include new Shopify API key tables
    
    ✨ (hasura/app/migrations): add new SQL migration for apiKeyStatus and shopifyApiKey tables
    ✨ (libs/crypto): introduce new crypto utility functions and update generateApiKeyId format
    🔧 (libs/features/back-office/shopify-api-keys): add ESLint, SWC config, README, and Jest setup for shopify-api-keys library
    
    ✨ (shopify-api-keys): add new library for Shopify API key management
    
    This commit introduces a new library within the back-office feature set, specifically designed for managing Shopify API keys. It includes functionality for creating and retrieving both public and secret Shopify API keys, adhering to security best practices by hashing and securely storing secret keys. The library is structured to support future scalability and maintainability, with clear separation of concerns and adherence to modern TypeScript practices. This addition lays the groundwork for integrating Shopify's API more seamlessly into the platform, enabling more robust e-commerce features and capabilities for back-office users.
    
    ✨ Add Shopify API key management GraphQL queries and mutations
    🔧 Update tsconfig for Shopify API keys feature and base project settings
    
    ✨ Add API_SECRET_ENCRYPTION_KEY to .env.local for enhanced security
    ✨ Create new API route for Shopify loyalty card with POST and GET methods
    ♻️ Refactor Hasura metadata by adding new tables for API keys and removing shopifySecretApiKey table
    🔧 Update Hasura metadata configuration to include new tables and remove deprecated ones
    
    ✨ (down.sql): introduce apiKeyType table to categorize API keys by type
    ♻️ (down.sql): refactor shopifyApiKey table to publishableApiKey for general use
    ♻️ (down.sql): refactor shopifySecretApiKey table to secretApiKey with enhanced security fields
    📝 (down.sql): update comments to reflect new table structures and purposes
    
    ✨ (up.sql): Introduce apiKeyType table to categorize API keys
    ♻️ (up.sql): Refactor shopifyApiKey to publishableApiKey for general use
    ♻️ (up.sql): Refactor shopifySecretApiKey to secretApiKey with enhanced security fields
    📝 (up.sql): Update comments to reflect new table structures and purposes
    
    ✨ (crypto lib): add encryption and decryption functions for secrets
    ♻️ (crypto lib): streamline API key generation by removing underscore
    🔧 (env/server): add API_SECRET_ENCRYPTION_KEY to environment variables
    🗑️ (shopify-api-keys): remove shopify-api-keys library and its references
    
    ♻️ refactor(api-keys): migrate Shopify API key logic to new api-keys lib
    
    - Deleted Shopify API key logic from `back-office/shopify-api-keys` to avoid duplication and centralize API key management.
    - Introduced new GraphQL mutations and queries for publishable and secret API keys in `admin/api` to replace Shopify-specific ones, enhancing flexibility and maintainability.
    - Added ESLint and SWC configurations to `api-keys` library for consistent code quality and faster compilation.
    - Created README and Jest config for `api-keys` library to document usage and ensure code quality through testing.
    
    ✨ Add new library for API key integrations with setup and initial functionality
    
    ✨ (tsconfig.spec.json): add tsconfig for API keys integration tests to support Jest and Node types
    
    ♻️ (tsconfig.base.json): Refactor paths to improve readability and maintainability
    ✨ (tsconfig.base.json): Add "@integrations/api-keys" path for better modularization of API keys integration
    
    ♻️ (tsconfig.base.json): reformat paths for clarity and maintainability
    
    ♻️ (tsconfig.base.json): reformat paths and compiler options for better readability
    
    ✨ (project.json): rename project to 'integrations-api-keys' for clarity
    ✨ (index.spec.ts, index.ts): add 'inputSecretKey' function to handle secret API key creation with origin and integrity secrets
    ✨ (external-api-handlers/src/index.ts): export 'ShopifyWebhookAndApiHandler' for Shopify integration
    🔧 (env/index.d.ts): add 'API_SECRET_ENCRYPTION_KEY' to environment types for secure API key handling
    
    ✨ (GraphQL mutations and queries): add 'type' field to support different API key types
    ♻️ (external-api-handlers): refactor API handler to use 'integritySecret' and improve signature verification methods
    ✅ (external-api-handlers tests): update tests to reflect changes in API handler methods and add new tests for deserialization and request timestamp guarding
    
    ♻️ refactor(external-api-handlers): overhaul BaseWebhookAndApiHandler for flexibility
    ✨ feat(external-api-handlers): add ShopifyWebhookAndApiHandler for Shopify integrations
    ♻️ refactor(nft/loyalty-card): export interfaces for external use
    
    ✨ (utils): add `isOriginAllowed` function to check origin against allowlist
    
    ✅ (utils): add tests for `isOriginAllowed` function to ensure correct behavior across various scenarios
    
    ♻️ (tsconfig.base.json): streamline paths configuration for better readability
    
    ♻️ (tsconfig.base.json): streamline tsconfig paths by removing duplicates and consolidating entries for better maintainability
    
    ♻️ (tsconfig.base.json): streamline tsconfig paths and cleanup formatting for better readability
    
    ✨ (crypto): export decryptSecret and encryptSecret functions for external use
    ♻️ (external-api-handlers): adjust timestamp calculation to use milliseconds
    ✅ (external-api-handlers): add tests for ShopifyWebhookAndApiHandler to ensure functionality and error handling
    
    ♻️ (shopify.ts): refactor import of decryptSecret for consistency
    ✨ (shopify.ts): add missing API key and invalid signature error handling
    ♻️ (shopify.ts): simplify signature verification logic in Shopify handler
    ✨ (shopify.ts): make allowlist check conditional to enhance flexibility
    
    ✨ (shopify.spec.ts): add tests for mintLoyaltyCardWithPassword functionality
    ♻️ (shopify.spec.ts): refactor API key type check in tests for clarity
    📝 (shopify.spec.ts): update documentation and mocks to support new tests
    
    ✨ (shopify.ts): Implement request validation and error handling for Shopify integration
    📝 (next/api-handler): Add documentation, configs, and setup for `next-api-handler` library
    ✨ (next/api-handler): Introduce `next-api-handler` library for structured API handling in Next.js projects
    
    ✨ Add custom error handling framework for API requests
    
    - Introduced a new library `@next/api-handler` for handling API errors in a standardized way across Next.js applications.
    - Implemented custom error classes (`BadRequestError`, `NotAuthorizedError`, `NotFoundError`, `InternalServerError`) extending a base `CustomError` class to represent different HTTP response statuses.
    - Created `handleApiRequest` function to wrap API handlers, providing centralized error handling and response formatting.
    - Integrated custom error handling into `@nft/loyalty-card` library, replacing generic `Error` instances with specific error types (`BadRequestError`, `NotFoundError`) to improve error specificity and client-side error handling.
    - Updated `tsconfig.base.json` to include `@next/api-handler` path, ensuring proper module resolution across the monorepo.
    - Added comprehensive tests for `handleApiRequest` to verify correct handling of both expected and unexpected errors, ensuring robustness and reliability of the error handling mechanism.
    
    ✨ (shopify/loyalty-card route): Integrate ShopifyWebhookAndApiHandler for POST requests
    📝 (shopify.ts): Remove unnecessary comment and refactor mintLoyaltyCardWithPassword method
    ♻️ (shopify/loyalty-card route): Refactor request type from any to NextRequest for type safety
    
    ✨ Add new crypto utility functions and types for enhanced security operations
    
    ✨ Update API key ID generation logic to support optional prefixes
    
    🔧 Increase API_SECRET_ENCRYPTION_KEY length requirement for improved security
    
    ♻️ Refactor imports in api-keys module for consistency
    
    ✅ Update tests to reflect new API key ID generation logic and add environment variables for comprehensive testing setup
    
    ♻️ Refactor chainId handling across loyalty card feature
    - Remove direct chainId references in favor of dynamic retrieval from `getCurrentChain()` to ensure consistency and flexibility across different environments.
    
    🔥 Remove unused GET handler in loyalty card route
    - Comment out unused GET function to clean up the codebase and focus on currently utilized endpoints.
    
    🔧 Update next.config.js to comment out experimental esmExternals configuration
    - Temporarily disable esmExternals setting to address module import issues, pending a more permanent solution.
    
    ✅ Update tests to mock new dependencies and adjust for chainId handling changes
    - Adapt unit tests to reflect changes in chainId sourcing and mock newly introduced dependencies to ensure test suite accuracy.
    
    ⬆️ Update SupportedNetworks and AddEthereumChainParameter definitions
    - Redefine enums and interfaces locally to remove dependency on `@web3-react/types`, increasing control over supported networks and chain parameters.
    
    🧹 Clean up package.json by removing unused dependency `@web3-react/types`
    - Streamline dependencies by removing an unused package, reducing potential for conflicts and unnecessary overhead.
    
    💡 Add comments and clean up imports across modified files
    - Improve code readability and maintenance by clarifying changes and removing unused imports.
    
    ♻️ (next.config.js): remove esmExternals experimental config due to resolved ESM import issue
    ✨ (shopify.ts): add HasLoyaltyCard request type and params validation for enhanced API functionality
    
    external api handlers shopify : get route with hasLoyaltyCard and unit test
    
    indexer alchemy webhooks loyaltyCard : create loyalty card webhook and unit test for it
    
    loyalty card cron and webhook : unit and integration tests
    
    remove useless console.log
    
    loyalty card activity : added sql verification for onwerAddress after webhook
    
    loyalty card cron : delete useless rule in eslintrc
    
    loyalty card cron : add ignore path pattern in jest config
    🔥 (down.sql): remove migration file for nftStatus_loyaltyCardNft due to inability to auto-generate down migration
    
    🔥 (hasura/migrations): remove nftStatus and loyaltyCardNft migration to streamline database schema
    
    🔥 (hasura/app/migrations): remove down migration for 1710952105946_stampNft due to inability to auto-generate reverse operations
    
    🔥 (hasura/app/migrations): remove migration 1710952105946_stampNft to revert changes
    
    🔥 Remove NFT transfer, minter wallet update, and mint password migrations
    
    🔥 Remove nftMintPassword and apiKey tables and related triggers/functions to streamline database schema and improve data management efficiency
    
    🔥 Remove apiKey and shopifyDomain tables and related comments from migrations
    
    ✨ (down.sql): add down migration scripts for init_shopify to enable rollback capabilities
    
    ✨ Add new columns, triggers, and tables for NFT, event, and campaign management
    ♻️ Standardize naming conventions and enforce lowercase for blockchain addresses
    📝 Update documentation comments for clarity and consistency in database schema
    
    ✨ Add new tables and relationships for NFT and loyalty card management
    📝 Add comments to tables and columns for better understanding of the schema
    ♻️ Implement triggers and functions to maintain data integrity and enforce lowercase addresses
    🔧 Update existing tables to align with new NFT status management system
    
    ✨ Create loyaltyCardNftContract table with unique constraints and comments for NFT-based loyalty cards
    📝 Add detailed comments on table and columns to explain the purpose and significance of each field in the context of NFT-based loyalty programs
    🚀 Implement triggers for automatic update timestamp and enforcing lowercase for contractAddress on insert
    
    ✨ (hasura/migrations): initialize Shopify integration with new tables and triggers
    
    - Create loyaltyCardStatus, loyaltyCardParameters, loyaltyCardNftContract, nftStatus, and loyaltyCardNft tables to support loyalty card management and NFT status tracking.
    - Introduce shopifyCampaignStatus table for managing Shopify campaign statuses.
    - Implement triggers and functions for automatic timestamp updates and enforcing lowercase for specific fields to ensure data consistency and integrity.
    - Establish foreign key relationships and unique indexes to maintain data integrity across related entities.
    - Add comprehensive comments to tables and columns for clarity and documentation purposes.
    
    ✨ Create tables for Shopify campaign parameters, stamp NFT contracts, tokens, and supply tracking; add related triggers and functions for data integrity and normalization
    📝 Add comprehensive comments to explain the purpose and relationships of new tables and columns in the database schema
    ♻️ Refactor nftTransfer table to support stamp NFT transfers, including adding new columns and updating check constraints for data validation
    ✨ Introduce minterTemporaryWallet enhancements to link with campaigns and loyalty cards, supporting targeted minting operations
    ✨ Create nftMintPassword table to manage secure minting operations through password protection, enhancing security and control over NFT minting processes
    
    ✨ Add comprehensive comments to database schema for clarity and context
    ✨ Implement triggers and functions for data integrity and automatic updates
    ♻️ Rename columns for consistency and clarity in webhook management
    ✨ Introduce new tables for API key management and Shopify integration
    🔧 Add unique constraints and indexes for optimized data access and integrity
    
    🔥 Remove shopifyCustomer migration files for cleanup
    ✨ (LoyaltyCardPage.stories.tsx): Disable chromatic tests for LoyaltyCardPage
    …ject style
    
    🔧 (package.json): move pnpm version requirement from packageManager to engines for better compatibility management
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    UNLOCK-4: Implement Key (Loyalty Card Contract)
    2 participants