Adocommerce Kit resolves models through a registry, so host subclasses keep relations and services pointed at the same class.
Publish the subclass
node ace commerce:extend productThe command creates app/models/commerce/product.ts and wires the loader into config/commerce.ts.
import { column } from "@adonisjs/lucid/orm";
import { Product } from "@adocommercekit/core/models";
export default class HostProduct extends Product {
@column()
declare brand: string | null;
}Add the schema change as a host migration. Adocommerce Kit never mutates host columns on your behalf.
this.schema.alterTable("commerce_products", (table) => {
table.string("brand").nullable();
});Extend the transformer separately
Database shape and public shape are separate decisions.
import { ProductTransformer } from "@adocommercekit/core/transformers";
import type HostProduct from "#models/commerce/product";
export default class HostProductTransformer extends ProductTransformer {
declare protected resource: HostProduct;
withBrand() {
return { ...this.forStorefront(), brand: this.resource.brand };
}
}Use the new variant from a host-owned controller. Generated frontend Data.* types will include it after Adonis indexes transformers.
Rules
- Keep registry keys unchanged; replace their loader.
- Extend the model that owns the column. Do not patch the base prototype.
- Write a migration for every new column or index.
- Preserve inherited decorators and relation names expected by core services.
- Preload any new relationship in the controller. Transformers must not trigger queries.