medusajs / examples

All Medusa-related examples.
29 stars 13 forks source link

Truncated link identifier collision #9

Closed xkisu closed 2 months ago

xkisu commented 2 months ago

Wasn't sure if I should file this in the core medusa repository or this one - I'm happy to make a new issue in the core if needed :)

I've been testing the v2 preview for a project, using a modified version of the digital product example. My only modifications where changing the "digital" name/identifier to a platform-specific name ("cloudprinter") for my own extension (i.e. "digitalProduct" -> "cloudprinterProduct").

The lengthening of the name causes issues with module linking, due to the database names generated by db:sync-links being longer than the 63 character limit imposed by Postgres. The truncated names start to collide, and make syncing the module links fail.

Error from npx medusa db:sync-links:

info:    Syncing links...
error:   
      INSERT INTO "link_module_migrations" (table_name, link_descriptor) VALUES ('cloudprinterProductModule_cloudprinter_product_order_order_order', '{"fromModule":"cloudprinterProductModuleService","toModule":"order","fromModel":"cloudprinter_product_order","toModel":"order"}');
      create table "cloudprinterProductModule_cloudprinter_product_order_order_order" ("cloudprinter_product_order_id" varchar(255) not null, "order_id" varchar(255) not null, "id" varchar(255) not null, "created_at" timestamptz(0) not null default CURRENT_TIMESTAMP, "updated_at" timestamptz(0) not null default CURRENT_TIMESTAMP, "deleted_at" timestamptz(0) null, constraint "cloudprinterProductModule_cloudprinter_product_order_order_order_pkey" primary key ("cloudprinter_product_order_id", "order_id"));
create index "IDX_order_id_-42c6436e" on "cloudprinterProductModule_cloudprinter_product_order_order_order" ("order_id");
create index "IDX_id_-42c6436e" on "cloudprinterProductModule_cloudprinter_product_order_order_order" ("id");
create index "IDX_cloudprinter_product_order_id_-42c6436e" on "cloudprinterProductModule_cloudprinter_product_order_order_order" ("cloudprinter_product_order_id");
create index "IDX_deleted_at_-42c6436e" on "cloudprinterProductModule_cloudprinter_product_order_order_order" ("deleted_at");

     - relation "cloudprinterProductModule_cloudprinter_product_order_order_orde" already exists

I ran the provided SQL manually with extra debugging, and the issue became apparent:

medusa> INSERT INTO "link_module_migrations" (table_name, link_descriptor) VALUES ('cloudprinterProductModule_cloudprinter_product_order_order_order', '{"fromModule":"cloudprinterProductModuleService","toModule":"order","fromModel":"cloudprinter_product_order","toModel":"order"}')
[2024-09-10 17:26:47] 1 row affected in 115 ms
medusa> create table "cloudprinterProductModule_cloudprinter_product_order_order_order" ("cloudprinter_product_order_id" varchar(255) not null, "order_id" varchar(255) not null, "id" varchar(255) not null, "created_at" timestamptz(0) not null default CURRENT_TIMESTAMP, "updated_at" timestamptz(0) not null default CURRENT_TIMESTAMP, "deleted_at" timestamptz(0) null, constraint "cloudprinterProductModule_cloudprinter_product_order_order_order_pkey" primary key ("cloudprinter_product_order_id", "order_id"))
[2024-09-10 17:26:48] [42622] identifier "cloudprinterProductModule_cloudprinter_product_order_order_order" will be truncated to "cloudprinterProductModule_cloudprinter_product_order_order_orde"
[2024-09-10 17:26:48] [42622] identifier "cloudprinterProductModule_cloudprinter_product_order_order_order_pkey" will be truncated to "cloudprinterProductModule_cloudprinter_product_order_order_orde"
[2024-09-10 17:26:48] [42P07] ERROR: relation "cloudprinterProductModule_cloudprinter_product_order_order_orde" already exists

Postgres is truncating both of these identifiers create by db:sync-links to 63 characters:

This is also an issue with the product variant link, but it hits the order link first and doesn't get there.

Which causes them both to be changed to cloudprinterProductModule_cloudprinter_product_order_order_orde, which then causes them to conflict with each other and fail the transition.

For now, I've used the link options to shorten the identifiers:

// src/links/cloudprinter-product-order.tsx
import OrderModule from "@medusajs/order"
import { defineLink } from "@medusajs/utils"

import CloudprinterProductModule from "../modules/cloudprinter-product"

export default defineLink(
    {
        linkable: CloudprinterProductModule.linkable.cloudprinterProductOrder,
        deleteCascade: true,
        // fix the generated table name:
        //  'cloudprinterProductModule_cloudprinter_product_order_order_order'
        // being longer then the 63 character limit.
        primaryKey: 'cloudprinterProduct_cloudprinter_product_order_order_pkey'
    },
    OrderModule.linkable.order,
    {
        database: {
            // fix the generated table name
            //  'cloudprinterProductModule_cloudprinter_product_order_order_order_pkey'
            // being longer then the 63 character limit.
            table: 'cloudprinterProduct_cloudprinter_product_order_order'
        }
    }
)
// src/links/cloudprinter-product-variant.tsx
import ProductModule from "@medusajs/product"
import { defineLink } from "@medusajs/utils"

import CloudprinterProductModule from "../modules/cloudprinter-product"

export default defineLink(
    {
        linkable: CloudprinterProductModule.linkable.cloudprinterProduct,

        // fix the generated table name:
        //  'cloudprinterProductModule_cloudprinter_product_product_product_variant_pkey'
        // being longer then the 63 character limit.
        primaryKey: 'cloudprinterProduct_cloudprinter_product_product_variant_pkey'
    },
    ProductModule.linkable.productVariant,
    {
        database: {
            // fix the generated table name
            //  'cloudprinterProductModule_cloudprinter_product_product_product_variant'
            // being longer then the 63 character limit.
            table: 'cloudprinterProduct_cloudprinter_product_product_variant'
        }
    }
)

I figured this might be something that the docs and the db:sync-links command might want to warn about, since the 63 character hard limit is enforced by Postegres (and can't be changed without compiling a custom version of Postgres).

shahednasser commented 2 months ago

Thanks for reporting this @xkisu , I believe this is a bug that should be handled by the command rather than something added to the doc. I'll close this issue here, but can you open it in the main medusajs monorepo? thanks again!

xkisu commented 2 months ago

Thanks for reporting this @xkisu , I believe this is a bug that should be handled by the command rather than something added to the doc. I'll close this issue here, but can you open it in the main medusajs monorepo? thanks again!

Sure thing!

https://github.com/medusajs/medusa/issues/9134