@endora-commerce/mod-quote-requests 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/admin/index.d.ts +26 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +56 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/RfqCreatePage.d.ts +9 -0
- package/dist/admin/pages/RfqCreatePage.d.ts.map +1 -0
- package/dist/admin/pages/RfqCreatePage.js +163 -0
- package/dist/admin/pages/RfqCreatePage.js.map +1 -0
- package/dist/admin/pages/RfqDetail.d.ts +9 -0
- package/dist/admin/pages/RfqDetail.d.ts.map +1 -0
- package/dist/admin/pages/RfqDetail.js +399 -0
- package/dist/admin/pages/RfqDetail.js.map +1 -0
- package/dist/admin/pages/RfqList.d.ts +9 -0
- package/dist/admin/pages/RfqList.d.ts.map +1 -0
- package/dist/admin/pages/RfqList.js +214 -0
- package/dist/admin/pages/RfqList.js.map +1 -0
- package/dist/admin/validity.d.ts +52 -0
- package/dist/admin/validity.d.ts.map +1 -0
- package/dist/admin/validity.js +61 -0
- package/dist/admin/validity.js.map +1 -0
- package/dist/backend/entities/quote-request-event.entity.d.ts +24 -0
- package/dist/backend/entities/quote-request-event.entity.d.ts.map +1 -0
- package/dist/backend/entities/quote-request-event.entity.js +67 -0
- package/dist/backend/entities/quote-request-event.entity.js.map +1 -0
- package/dist/backend/entities/quote-request-item.entity.d.ts +34 -0
- package/dist/backend/entities/quote-request-item.entity.d.ts.map +1 -0
- package/dist/backend/entities/quote-request-item.entity.js +119 -0
- package/dist/backend/entities/quote-request-item.entity.js.map +1 -0
- package/dist/backend/entities/quote-request-notification-event.entity.d.ts +23 -0
- package/dist/backend/entities/quote-request-notification-event.entity.d.ts.map +1 -0
- package/dist/backend/entities/quote-request-notification-event.entity.js +72 -0
- package/dist/backend/entities/quote-request-notification-event.entity.js.map +1 -0
- package/dist/backend/entities/quote-request-revision.entity.d.ts +35 -0
- package/dist/backend/entities/quote-request-revision.entity.d.ts.map +1 -0
- package/dist/backend/entities/quote-request-revision.entity.js +67 -0
- package/dist/backend/entities/quote-request-revision.entity.js.map +1 -0
- package/dist/backend/entities/quote-request.entity.d.ts +90 -0
- package/dist/backend/entities/quote-request.entity.d.ts.map +1 -0
- package/dist/backend/entities/quote-request.entity.js +191 -0
- package/dist/backend/entities/quote-request.entity.js.map +1 -0
- package/dist/backend/index.d.ts +120 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +361 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/plugin.d.ts +95 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +152 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +13 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +82 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.customer.d.ts +18 -0
- package/dist/backend/routes.customer.d.ts.map +1 -0
- package/dist/backend/routes.customer.js +98 -0
- package/dist/backend/routes.customer.js.map +1 -0
- package/dist/backend/routes.sales-reps.d.ts +12 -0
- package/dist/backend/routes.sales-reps.d.ts.map +1 -0
- package/dist/backend/routes.sales-reps.js +57 -0
- package/dist/backend/routes.sales-reps.js.map +1 -0
- package/dist/backend/services/order-completion-reactor.d.ts +32 -0
- package/dist/backend/services/order-completion-reactor.d.ts.map +1 -0
- package/dist/backend/services/order-completion-reactor.js +57 -0
- package/dist/backend/services/order-completion-reactor.js.map +1 -0
- package/dist/backend/services/quote-request-business-id-generator.d.ts +46 -0
- package/dist/backend/services/quote-request-business-id-generator.d.ts.map +1 -0
- package/dist/backend/services/quote-request-business-id-generator.js +69 -0
- package/dist/backend/services/quote-request-business-id-generator.js.map +1 -0
- package/dist/backend/services/quote-request-read-port.d.ts +36 -0
- package/dist/backend/services/quote-request-read-port.d.ts.map +1 -0
- package/dist/backend/services/quote-request-read-port.js +96 -0
- package/dist/backend/services/quote-request-read-port.js.map +1 -0
- package/dist/backend/services/raised-on-channel.d.ts +23 -0
- package/dist/backend/services/raised-on-channel.d.ts.map +1 -0
- package/dist/backend/services/raised-on-channel.js +26 -0
- package/dist/backend/services/raised-on-channel.js.map +1 -0
- package/dist/backend/services/rfq-admin-service.d.ts +75 -0
- package/dist/backend/services/rfq-admin-service.d.ts.map +1 -0
- package/dist/backend/services/rfq-admin-service.js +487 -0
- package/dist/backend/services/rfq-admin-service.js.map +1 -0
- package/dist/backend/services/rfq-event-service.d.ts +32 -0
- package/dist/backend/services/rfq-event-service.d.ts.map +1 -0
- package/dist/backend/services/rfq-event-service.js +28 -0
- package/dist/backend/services/rfq-event-service.js.map +1 -0
- package/dist/backend/services/rfq-expiry-worker.d.ts +50 -0
- package/dist/backend/services/rfq-expiry-worker.d.ts.map +1 -0
- package/dist/backend/services/rfq-expiry-worker.js +70 -0
- package/dist/backend/services/rfq-expiry-worker.js.map +1 -0
- package/dist/backend/services/rfq-notification-service.d.ts +36 -0
- package/dist/backend/services/rfq-notification-service.d.ts.map +1 -0
- package/dist/backend/services/rfq-notification-service.js +52 -0
- package/dist/backend/services/rfq-notification-service.js.map +1 -0
- package/dist/backend/services/rfq-revision-service.d.ts +70 -0
- package/dist/backend/services/rfq-revision-service.d.ts.map +1 -0
- package/dist/backend/services/rfq-revision-service.js +120 -0
- package/dist/backend/services/rfq-revision-service.js.map +1 -0
- package/dist/backend/services/rfq-service.d.ts +140 -0
- package/dist/backend/services/rfq-service.d.ts.map +1 -0
- package/dist/backend/services/rfq-service.js +786 -0
- package/dist/backend/services/rfq-service.js.map +1 -0
- package/dist/backend/services/sales-channel-attributions.d.ts +38 -0
- package/dist/backend/services/sales-channel-attributions.d.ts.map +1 -0
- package/dist/backend/services/sales-channel-attributions.js +48 -0
- package/dist/backend/services/sales-channel-attributions.js.map +1 -0
- package/dist/manifest.d.ts +203 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +277 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260424T190112_quote_requests_init.d.ts +19 -0
- package/dist/migrations/20260424T190112_quote_requests_init.d.ts.map +1 -0
- package/dist/migrations/20260424T190112_quote_requests_init.js +65 -0
- package/dist/migrations/20260424T190112_quote_requests_init.js.map +1 -0
- package/dist/migrations/20260503T141344_quote_requests_workflow.d.ts +37 -0
- package/dist/migrations/20260503T141344_quote_requests_workflow.d.ts.map +1 -0
- package/dist/migrations/20260503T141344_quote_requests_workflow.js +251 -0
- package/dist/migrations/20260503T141344_quote_requests_workflow.js.map +1 -0
- package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.d.ts +10 -0
- package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.d.ts.map +1 -0
- package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.js +16 -0
- package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.js.map +1 -0
- package/dist/migrations/20260611T140417_quote_requests_business_id.d.ts +24 -0
- package/dist/migrations/20260611T140417_quote_requests_business_id.d.ts.map +1 -0
- package/dist/migrations/20260611T140417_quote_requests_business_id.js +34 -0
- package/dist/migrations/20260611T140417_quote_requests_business_id.js.map +1 -0
- package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts +21 -0
- package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts.map +1 -0
- package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.js +29 -0
- package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.js.map +1 -0
- package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.d.ts +12 -0
- package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.d.ts.map +1 -0
- package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.js +16 -0
- package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.js.map +1 -0
- package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.d.ts +34 -0
- package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.d.ts.map +1 -0
- package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.js +57 -0
- package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.js.map +1 -0
- package/dist/migrations/index.d.ts +53 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +61 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/status-mapping.d.ts +18 -0
- package/dist/migrations/status-mapping.d.ts.map +1 -0
- package/dist/migrations/status-mapping.js +28 -0
- package/dist/migrations/status-mapping.js.map +1 -0
- package/docs/quote_requests.md +168 -0
- package/i18n/en.json +14 -0
- package/i18n/pl.json +14 -0
- package/package.json +99 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* quote_requests module — Phase 3.5 (T075).
|
|
4
|
+
*
|
|
5
|
+
* Schema notes:
|
|
6
|
+
* - Foreign keys to customer_accounts / organizations / admin_users stay as
|
|
7
|
+
* plain uuid columns without FK constraints: those target tables ship in
|
|
8
|
+
* US2/US3/US4. FKs get added by their respective migrations.
|
|
9
|
+
* - Partial unique index on (organization_id, customer_account_id) WHERE
|
|
10
|
+
* status='draft' enforces "one open draft per customer per organization"
|
|
11
|
+
* (tasks.md T075).
|
|
12
|
+
* - `version` column drives optimistic concurrency — the `If-Match` header
|
|
13
|
+
* path uses a CAS `UPDATE ... WHERE version = $expected`.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Migration20260424T190112QuoteRequestsInit extends Migration {
|
|
16
|
+
up(): Promise<void>;
|
|
17
|
+
down(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=20260424T190112_quote_requests_init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260424T190112_quote_requests_init.d.ts","sourceRoot":"","sources":["../../src/migrations/20260424T190112_quote_requests_init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,qBAAa,yCAA0C,SAAQ,SAAS;IACvD,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAIrC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* quote_requests module — Phase 3.5 (T075).
|
|
4
|
+
*
|
|
5
|
+
* Schema notes:
|
|
6
|
+
* - Foreign keys to customer_accounts / organizations / admin_users stay as
|
|
7
|
+
* plain uuid columns without FK constraints: those target tables ship in
|
|
8
|
+
* US2/US3/US4. FKs get added by their respective migrations.
|
|
9
|
+
* - Partial unique index on (organization_id, customer_account_id) WHERE
|
|
10
|
+
* status='draft' enforces "one open draft per customer per organization"
|
|
11
|
+
* (tasks.md T075).
|
|
12
|
+
* - `version` column drives optimistic concurrency — the `If-Match` header
|
|
13
|
+
* path uses a CAS `UPDATE ... WHERE version = $expected`.
|
|
14
|
+
*/
|
|
15
|
+
export class Migration20260424T190112QuoteRequestsInit extends Migration {
|
|
16
|
+
async up() {
|
|
17
|
+
this.addSql(`
|
|
18
|
+
create table "quote_requests" (
|
|
19
|
+
"id" uuid not null,
|
|
20
|
+
"organization_id" uuid not null,
|
|
21
|
+
"customer_account_id" uuid not null,
|
|
22
|
+
"status" varchar(32) not null default 'draft',
|
|
23
|
+
"requester_note" text null,
|
|
24
|
+
"assigned_admin_user_id" uuid null,
|
|
25
|
+
"submitted_at" timestamptz null,
|
|
26
|
+
"quoted_at" timestamptz null,
|
|
27
|
+
"responded_at" timestamptz null,
|
|
28
|
+
"expires_at" timestamptz null,
|
|
29
|
+
"quote_terms" jsonb null,
|
|
30
|
+
"version" int not null default 0,
|
|
31
|
+
"created_at" timestamptz not null,
|
|
32
|
+
"updated_at" timestamptz not null,
|
|
33
|
+
constraint "quote_requests_pkey" primary key ("id")
|
|
34
|
+
);
|
|
35
|
+
`);
|
|
36
|
+
this.addSql('create index "quote_requests_organization_id_index" on "quote_requests" ("organization_id");');
|
|
37
|
+
this.addSql('create index "quote_requests_customer_account_id_index" on "quote_requests" ("customer_account_id");');
|
|
38
|
+
this.addSql('create index "quote_requests_status_index" on "quote_requests" ("status");');
|
|
39
|
+
this.addSql(`create unique index "quote_requests_one_draft_per_customer" on "quote_requests" ("organization_id", "customer_account_id") where "status" = 'draft';`);
|
|
40
|
+
this.addSql(`
|
|
41
|
+
create table "quote_request_items" (
|
|
42
|
+
"id" uuid not null,
|
|
43
|
+
"quote_request_id" uuid not null,
|
|
44
|
+
"product_id" uuid not null,
|
|
45
|
+
"product_name" varchar(255) not null,
|
|
46
|
+
"variant_id" uuid null,
|
|
47
|
+
"variant_label" varchar(255) null,
|
|
48
|
+
"quantity" int not null,
|
|
49
|
+
"requester_note" text null,
|
|
50
|
+
"quoted_unit_price" numeric(12,2) null,
|
|
51
|
+
"quoted_discount_percent" numeric(5,2) null,
|
|
52
|
+
"created_at" timestamptz not null,
|
|
53
|
+
"updated_at" timestamptz not null,
|
|
54
|
+
constraint "quote_request_items_pkey" primary key ("id"),
|
|
55
|
+
constraint "quote_request_items_rfq_fk" foreign key ("quote_request_id") references "quote_requests" ("id") on delete cascade
|
|
56
|
+
);
|
|
57
|
+
`);
|
|
58
|
+
this.addSql('create index "quote_request_items_quote_request_id_index" on "quote_request_items" ("quote_request_id");');
|
|
59
|
+
}
|
|
60
|
+
async down() {
|
|
61
|
+
this.addSql('drop table if exists "quote_request_items" cascade;');
|
|
62
|
+
this.addSql('drop table if exists "quote_requests" cascade;');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=20260424T190112_quote_requests_init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260424T190112_quote_requests_init.js","sourceRoot":"","sources":["../../src/migrations/20260424T190112_quote_requests_init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,yCAA0C,SAAQ,SAAS;IAC7D,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;KAkBX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,8FAA8F,CAAC,CAAC;QAC5G,IAAI,CAAC,MAAM,CAAC,sGAAsG,CAAC,CAAC;QACpH,IAAI,CAAC,MAAM,CAAC,4EAA4E,CAAC,CAAC;QAC1F,IAAI,CAAC,MAAM,CACT,sJAAsJ,CACvJ,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;KAiBX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,0GAA0G,CAAC,CAAC;IAC1H,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,qDAAqD,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,gDAAgD,CAAC,CAAC;IAChE,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Quote Requests workflow rewrite (feature 008).
|
|
4
|
+
*
|
|
5
|
+
* What this migration does, in order:
|
|
6
|
+
* 1. Renames quote_requests.requester_note → header_note (the "header note"
|
|
7
|
+
* attached to the whole RFQ, not a per-line note).
|
|
8
|
+
* 2. Adds new lifecycle columns: created_by_admin_user_id,
|
|
9
|
+
* cancellation_reason, awaiting_customer_revision_acceptance,
|
|
10
|
+
* last_customer_seen_revision_number, current_revision_number,
|
|
11
|
+
* approved_at, canceled_at, completed_at, expired_at, converted_order_id.
|
|
12
|
+
* 3. Maps legacy quote_requests.status values to the new six-status enum
|
|
13
|
+
* using mapLegacyStatus() — drops legacy `draft` rows, keeps the rest.
|
|
14
|
+
* 4. Drops the now-redundant legacy columns (quoted_at, responded_at,
|
|
15
|
+
* quote_terms) — the lifecycle data they encoded moves into
|
|
16
|
+
* quote_request_events / quote_request_revisions.
|
|
17
|
+
* 5. Renames quote_request_items.requester_note → line_note,
|
|
18
|
+
* quoted_unit_price → agreed_unit_price,
|
|
19
|
+
* quoted_discount_percent → discount_percent. Adds
|
|
20
|
+
* desired_unit_price, line_currency, product_slug.
|
|
21
|
+
* 6. Creates quote_request_revisions, quote_request_events,
|
|
22
|
+
* quote_request_notification_events.
|
|
23
|
+
* 7. Creates organization_sales_rep_assignments (lives in the organizations
|
|
24
|
+
* module logically — research.md §R9 — but the migration itself is
|
|
25
|
+
* colocated here for atomicity).
|
|
26
|
+
*
|
|
27
|
+
* The down() path is best-effort: it restores the legacy schema enough that
|
|
28
|
+
* a clean rebuild does not crash, but does NOT round-trip data written under
|
|
29
|
+
* the new schema. Spec accepts this trade-off (data-model.md §8).
|
|
30
|
+
*
|
|
31
|
+
* Spec references: data-model.md §1–§6, research.md §R1, §R9.
|
|
32
|
+
*/
|
|
33
|
+
export declare class Migration20260503T141344QuoteRequestsWorkflow extends Migration {
|
|
34
|
+
up(): Promise<void>;
|
|
35
|
+
down(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=20260503T141344_quote_requests_workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260503T141344_quote_requests_workflow.d.ts","sourceRoot":"","sources":["../../src/migrations/20260503T141344_quote_requests_workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,6CAA8C,SAAQ,SAAS;IAC3D,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAqMnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAoCrC"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Quote Requests workflow rewrite (feature 008).
|
|
4
|
+
*
|
|
5
|
+
* What this migration does, in order:
|
|
6
|
+
* 1. Renames quote_requests.requester_note → header_note (the "header note"
|
|
7
|
+
* attached to the whole RFQ, not a per-line note).
|
|
8
|
+
* 2. Adds new lifecycle columns: created_by_admin_user_id,
|
|
9
|
+
* cancellation_reason, awaiting_customer_revision_acceptance,
|
|
10
|
+
* last_customer_seen_revision_number, current_revision_number,
|
|
11
|
+
* approved_at, canceled_at, completed_at, expired_at, converted_order_id.
|
|
12
|
+
* 3. Maps legacy quote_requests.status values to the new six-status enum
|
|
13
|
+
* using mapLegacyStatus() — drops legacy `draft` rows, keeps the rest.
|
|
14
|
+
* 4. Drops the now-redundant legacy columns (quoted_at, responded_at,
|
|
15
|
+
* quote_terms) — the lifecycle data they encoded moves into
|
|
16
|
+
* quote_request_events / quote_request_revisions.
|
|
17
|
+
* 5. Renames quote_request_items.requester_note → line_note,
|
|
18
|
+
* quoted_unit_price → agreed_unit_price,
|
|
19
|
+
* quoted_discount_percent → discount_percent. Adds
|
|
20
|
+
* desired_unit_price, line_currency, product_slug.
|
|
21
|
+
* 6. Creates quote_request_revisions, quote_request_events,
|
|
22
|
+
* quote_request_notification_events.
|
|
23
|
+
* 7. Creates organization_sales_rep_assignments (lives in the organizations
|
|
24
|
+
* module logically — research.md §R9 — but the migration itself is
|
|
25
|
+
* colocated here for atomicity).
|
|
26
|
+
*
|
|
27
|
+
* The down() path is best-effort: it restores the legacy schema enough that
|
|
28
|
+
* a clean rebuild does not crash, but does NOT round-trip data written under
|
|
29
|
+
* the new schema. Spec accepts this trade-off (data-model.md §8).
|
|
30
|
+
*
|
|
31
|
+
* Spec references: data-model.md §1–§6, research.md §R1, §R9.
|
|
32
|
+
*/
|
|
33
|
+
export class Migration20260503T141344QuoteRequestsWorkflow extends Migration {
|
|
34
|
+
async up() {
|
|
35
|
+
// -- 1. Rename header note column -------------------------------
|
|
36
|
+
this.addSql(`alter table "quote_requests" rename column "requester_note" to "header_note";`);
|
|
37
|
+
// -- 2. Add new lifecycle columns -------------------------------
|
|
38
|
+
this.addSql(`
|
|
39
|
+
alter table "quote_requests"
|
|
40
|
+
add column "created_by_admin_user_id" uuid null,
|
|
41
|
+
add column "cancellation_reason" text null,
|
|
42
|
+
add column "awaiting_customer_revision_acceptance" boolean not null default false,
|
|
43
|
+
add column "last_customer_seen_revision_number" int not null default 0,
|
|
44
|
+
add column "current_revision_number" int not null default 0,
|
|
45
|
+
add column "approved_at" timestamptz null,
|
|
46
|
+
add column "canceled_at" timestamptz null,
|
|
47
|
+
add column "completed_at" timestamptz null,
|
|
48
|
+
add column "expired_at" timestamptz null,
|
|
49
|
+
add column "converted_order_id" uuid null;
|
|
50
|
+
`);
|
|
51
|
+
// -- 3. Drop legacy partial unique index that referenced 'draft'.
|
|
52
|
+
// Has to be dropped BEFORE we remap statuses or the unique
|
|
53
|
+
// constraint can fire spuriously.
|
|
54
|
+
this.addSql(`drop index if exists "quote_requests_one_draft_per_customer";`);
|
|
55
|
+
// -- 4. Status mapping. Postgres lets us update the column
|
|
56
|
+
// in-place because it's stored as varchar(32), not a true
|
|
57
|
+
// enum type. The legacy CHECK is implicit (no constraint
|
|
58
|
+
// defined in 002).
|
|
59
|
+
// legacy 'draft' → DELETE row
|
|
60
|
+
// legacy 'new' → 'Pending'
|
|
61
|
+
// legacy 'under_review' → 'Pending'
|
|
62
|
+
// legacy 'quoted' → 'Pending' + awaiting_customer_revision_acceptance=true
|
|
63
|
+
// legacy 'accepted' → 'Approved' (+ approved_at = updated_at)
|
|
64
|
+
// legacy 'rejected' → 'Canceled' (+ canceled_at = updated_at)
|
|
65
|
+
// legacy 'expired' → 'Expired' (+ expired_at = updated_at)
|
|
66
|
+
this.addSql(`delete from "quote_requests" where "status" = 'draft';`);
|
|
67
|
+
this.addSql(`
|
|
68
|
+
update "quote_requests"
|
|
69
|
+
set "status" = 'Pending'
|
|
70
|
+
where "status" in ('new', 'under_review');
|
|
71
|
+
`);
|
|
72
|
+
this.addSql(`
|
|
73
|
+
update "quote_requests"
|
|
74
|
+
set "status" = 'Pending',
|
|
75
|
+
"awaiting_customer_revision_acceptance" = true,
|
|
76
|
+
"current_revision_number" = 1
|
|
77
|
+
where "status" = 'quoted';
|
|
78
|
+
`);
|
|
79
|
+
this.addSql(`
|
|
80
|
+
update "quote_requests"
|
|
81
|
+
set "status" = 'Approved',
|
|
82
|
+
"approved_at" = coalesce("responded_at", "updated_at")
|
|
83
|
+
where "status" = 'accepted';
|
|
84
|
+
`);
|
|
85
|
+
this.addSql(`
|
|
86
|
+
update "quote_requests"
|
|
87
|
+
set "status" = 'Canceled',
|
|
88
|
+
"canceled_at" = coalesce("responded_at", "updated_at")
|
|
89
|
+
where "status" = 'rejected';
|
|
90
|
+
`);
|
|
91
|
+
this.addSql(`
|
|
92
|
+
update "quote_requests"
|
|
93
|
+
set "status" = 'Expired',
|
|
94
|
+
"expired_at" = "updated_at"
|
|
95
|
+
where "status" = 'expired';
|
|
96
|
+
`);
|
|
97
|
+
// -- 5. Add the new CHECK constraint accepting only the six new values.
|
|
98
|
+
this.addSql(`
|
|
99
|
+
alter table "quote_requests"
|
|
100
|
+
add constraint "quote_requests_status_check"
|
|
101
|
+
check ("status" in ('Created from admin','Pending','Canceled','Approved','Completed','Expired'));
|
|
102
|
+
`);
|
|
103
|
+
// -- 6. Drop legacy columns now that all data has been migrated.
|
|
104
|
+
this.addSql(`alter table "quote_requests" drop column "quoted_at";`);
|
|
105
|
+
this.addSql(`alter table "quote_requests" drop column "responded_at";`);
|
|
106
|
+
this.addSql(`alter table "quote_requests" drop column "quote_terms";`);
|
|
107
|
+
// -- 7. Indexes for the expiry worker scan and the assignment-scoped lists.
|
|
108
|
+
this.addSql(`create index "idx_quote_requests_status_updated" on "quote_requests" ("status", "updated_at");`);
|
|
109
|
+
this.addSql(`create index "idx_quote_requests_org_status" on "quote_requests" ("organization_id", "status");`);
|
|
110
|
+
this.addSql(`create index "idx_quote_requests_customer_status" on "quote_requests" ("customer_account_id", "status");`);
|
|
111
|
+
// ============================================================
|
|
112
|
+
// quote_request_items
|
|
113
|
+
// ============================================================
|
|
114
|
+
this.addSql(`alter table "quote_request_items" rename column "requester_note" to "line_note";`);
|
|
115
|
+
this.addSql(`alter table "quote_request_items" rename column "quoted_unit_price" to "agreed_unit_price";`);
|
|
116
|
+
this.addSql(`alter table "quote_request_items" rename column "quoted_discount_percent" to "discount_percent";`);
|
|
117
|
+
this.addSql(`
|
|
118
|
+
alter table "quote_request_items"
|
|
119
|
+
add column "desired_unit_price" numeric(12,2) null,
|
|
120
|
+
add column "line_currency" varchar(3) null,
|
|
121
|
+
add column "product_slug" varchar(255) null;
|
|
122
|
+
`);
|
|
123
|
+
this.addSql(`update "quote_request_items" set "line_currency" = 'PLN' where "line_currency" is null;`);
|
|
124
|
+
this.addSql(`alter table "quote_request_items" alter column "line_currency" set not null;`);
|
|
125
|
+
// ============================================================
|
|
126
|
+
// quote_request_revisions
|
|
127
|
+
// ============================================================
|
|
128
|
+
this.addSql(`
|
|
129
|
+
create table "quote_request_revisions" (
|
|
130
|
+
"id" uuid not null,
|
|
131
|
+
"quote_request_id" uuid not null,
|
|
132
|
+
"revision_number" int not null,
|
|
133
|
+
"created_by_admin_user_id" uuid null,
|
|
134
|
+
"created_by_customer_account_id" uuid null,
|
|
135
|
+
"header_note_snapshot" text null,
|
|
136
|
+
"items_snapshot" jsonb not null,
|
|
137
|
+
"previous_revision_id" uuid null,
|
|
138
|
+
"created_at" timestamptz not null,
|
|
139
|
+
constraint "quote_request_revisions_pkey" primary key ("id"),
|
|
140
|
+
constraint "qrr_rfq_fk" foreign key ("quote_request_id") references "quote_requests" ("id") on delete cascade,
|
|
141
|
+
constraint "qrr_unique_per_rfq" unique ("quote_request_id", "revision_number")
|
|
142
|
+
);
|
|
143
|
+
`);
|
|
144
|
+
this.addSql(`create index "qrr_rfq_idx" on "quote_request_revisions" ("quote_request_id");`);
|
|
145
|
+
// ============================================================
|
|
146
|
+
// quote_request_events
|
|
147
|
+
// ============================================================
|
|
148
|
+
this.addSql(`
|
|
149
|
+
create table "quote_request_events" (
|
|
150
|
+
"id" uuid not null,
|
|
151
|
+
"quote_request_id" uuid not null,
|
|
152
|
+
"event_type" varchar(64) not null,
|
|
153
|
+
"actor_admin_user_id" uuid null,
|
|
154
|
+
"actor_customer_account_id" uuid null,
|
|
155
|
+
"actor_role_label" varchar(64) null,
|
|
156
|
+
"payload" jsonb not null,
|
|
157
|
+
"revision_id" uuid null,
|
|
158
|
+
"created_at" timestamptz not null,
|
|
159
|
+
constraint "quote_request_events_pkey" primary key ("id"),
|
|
160
|
+
constraint "qre_rfq_fk" foreign key ("quote_request_id") references "quote_requests" ("id") on delete cascade,
|
|
161
|
+
constraint "qre_event_type_check" check ("event_type" in (
|
|
162
|
+
'created','submitted','modified','approved','canceled','expired',
|
|
163
|
+
'completed','customer-accepted-revision','customer-rejected-revision',
|
|
164
|
+
're-submitted','note-added'
|
|
165
|
+
)),
|
|
166
|
+
constraint "qre_actor_xor" check (
|
|
167
|
+
("actor_admin_user_id" is null) <> ("actor_customer_account_id" is null)
|
|
168
|
+
or ("actor_admin_user_id" is null and "actor_customer_account_id" is null)
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
`);
|
|
172
|
+
this.addSql(`create index "qre_rfq_created_idx" on "quote_request_events" ("quote_request_id", "created_at");`);
|
|
173
|
+
// ============================================================
|
|
174
|
+
// quote_request_notification_events
|
|
175
|
+
// ============================================================
|
|
176
|
+
this.addSql(`
|
|
177
|
+
create table "quote_request_notification_events" (
|
|
178
|
+
"id" uuid not null,
|
|
179
|
+
"quote_request_id" uuid not null,
|
|
180
|
+
"source_event_id" uuid not null,
|
|
181
|
+
"recipient_admin_user_id" uuid null,
|
|
182
|
+
"recipient_customer_account_id" uuid null,
|
|
183
|
+
"channel" varchar(16) not null,
|
|
184
|
+
"status" varchar(16) not null,
|
|
185
|
+
"error" text null,
|
|
186
|
+
"enqueued_at" timestamptz not null,
|
|
187
|
+
"sent_at" timestamptz null,
|
|
188
|
+
constraint "quote_request_notification_events_pkey" primary key ("id"),
|
|
189
|
+
constraint "qrne_rfq_fk" foreign key ("quote_request_id") references "quote_requests" ("id") on delete cascade,
|
|
190
|
+
constraint "qrne_event_fk" foreign key ("source_event_id") references "quote_request_events" ("id") on delete cascade,
|
|
191
|
+
constraint "qrne_channel_check" check ("channel" in ('email','in_app')),
|
|
192
|
+
constraint "qrne_status_check" check ("status" in ('queued','sent','failed'))
|
|
193
|
+
);
|
|
194
|
+
`);
|
|
195
|
+
this.addSql(`
|
|
196
|
+
create unique index "qrne_dedupe_idx" on "quote_request_notification_events"
|
|
197
|
+
("quote_request_id", "source_event_id",
|
|
198
|
+
coalesce("recipient_admin_user_id", '00000000-0000-0000-0000-000000000000'::uuid),
|
|
199
|
+
coalesce("recipient_customer_account_id", '00000000-0000-0000-0000-000000000000'::uuid),
|
|
200
|
+
"channel");
|
|
201
|
+
`);
|
|
202
|
+
// ============================================================
|
|
203
|
+
// organization_sales_rep_assignments (organizations module — research §R9)
|
|
204
|
+
// ============================================================
|
|
205
|
+
this.addSql(`
|
|
206
|
+
create table "organization_sales_rep_assignments" (
|
|
207
|
+
"id" uuid not null,
|
|
208
|
+
"organization_id" uuid not null,
|
|
209
|
+
"admin_user_id" uuid not null,
|
|
210
|
+
"assigned_by_admin_user_id" uuid null,
|
|
211
|
+
"created_at" timestamptz not null,
|
|
212
|
+
constraint "organization_sales_rep_assignments_pkey" primary key ("id"),
|
|
213
|
+
constraint "orgsa_unique" unique ("organization_id", "admin_user_id")
|
|
214
|
+
);
|
|
215
|
+
`);
|
|
216
|
+
this.addSql(`create index "orgsa_admin_user_idx" on "organization_sales_rep_assignments" ("admin_user_id");`);
|
|
217
|
+
this.addSql(`create index "orgsa_organization_idx" on "organization_sales_rep_assignments" ("organization_id");`);
|
|
218
|
+
}
|
|
219
|
+
async down() {
|
|
220
|
+
// Best-effort rollback. Loses all data written under the new schema.
|
|
221
|
+
this.addSql(`drop table if exists "organization_sales_rep_assignments" cascade;`);
|
|
222
|
+
this.addSql(`drop table if exists "quote_request_notification_events" cascade;`);
|
|
223
|
+
this.addSql(`drop table if exists "quote_request_events" cascade;`);
|
|
224
|
+
this.addSql(`drop table if exists "quote_request_revisions" cascade;`);
|
|
225
|
+
this.addSql(`alter table "quote_request_items" drop column if exists "product_slug";`);
|
|
226
|
+
this.addSql(`alter table "quote_request_items" drop column if exists "line_currency";`);
|
|
227
|
+
this.addSql(`alter table "quote_request_items" drop column if exists "desired_unit_price";`);
|
|
228
|
+
this.addSql(`alter table "quote_request_items" rename column "discount_percent" to "quoted_discount_percent";`);
|
|
229
|
+
this.addSql(`alter table "quote_request_items" rename column "agreed_unit_price" to "quoted_unit_price";`);
|
|
230
|
+
this.addSql(`alter table "quote_request_items" rename column "line_note" to "requester_note";`);
|
|
231
|
+
this.addSql(`drop index if exists "idx_quote_requests_status_updated";`);
|
|
232
|
+
this.addSql(`drop index if exists "idx_quote_requests_org_status";`);
|
|
233
|
+
this.addSql(`drop index if exists "idx_quote_requests_customer_status";`);
|
|
234
|
+
this.addSql(`alter table "quote_requests" drop constraint if exists "quote_requests_status_check";`);
|
|
235
|
+
this.addSql(`alter table "quote_requests" add column "quoted_at" timestamptz null;`);
|
|
236
|
+
this.addSql(`alter table "quote_requests" add column "responded_at" timestamptz null;`);
|
|
237
|
+
this.addSql(`alter table "quote_requests" add column "quote_terms" jsonb null;`);
|
|
238
|
+
this.addSql(`alter table "quote_requests" drop column if exists "converted_order_id";`);
|
|
239
|
+
this.addSql(`alter table "quote_requests" drop column if exists "expired_at";`);
|
|
240
|
+
this.addSql(`alter table "quote_requests" drop column if exists "completed_at";`);
|
|
241
|
+
this.addSql(`alter table "quote_requests" drop column if exists "canceled_at";`);
|
|
242
|
+
this.addSql(`alter table "quote_requests" drop column if exists "approved_at";`);
|
|
243
|
+
this.addSql(`alter table "quote_requests" drop column if exists "current_revision_number";`);
|
|
244
|
+
this.addSql(`alter table "quote_requests" drop column if exists "last_customer_seen_revision_number";`);
|
|
245
|
+
this.addSql(`alter table "quote_requests" drop column if exists "awaiting_customer_revision_acceptance";`);
|
|
246
|
+
this.addSql(`alter table "quote_requests" drop column if exists "cancellation_reason";`);
|
|
247
|
+
this.addSql(`alter table "quote_requests" drop column if exists "created_by_admin_user_id";`);
|
|
248
|
+
this.addSql(`alter table "quote_requests" rename column "header_note" to "requester_note";`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=20260503T141344_quote_requests_workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260503T141344_quote_requests_workflow.js","sourceRoot":"","sources":["../../src/migrations/20260503T141344_quote_requests_workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Feature 043 — packaging-unit snapshot on quote-request lines. The unit name
|
|
4
|
+
* is also appended to `product_name`. Nullable — plain lines have none.
|
|
5
|
+
*/
|
|
6
|
+
export declare class Migration20260611T140415QuoteRequestsQrItemPackaging extends Migration {
|
|
7
|
+
up(): Promise<void>;
|
|
8
|
+
down(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=20260611T140415_quote_requests_qr_item_packaging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260611T140415_quote_requests_qr_item_packaging.d.ts","sourceRoot":"","sources":["../../src/migrations/20260611T140415_quote_requests_qr_item_packaging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;GAGG;AACH,qBAAa,oDAAqD,SAAQ,SAAS;IAClE,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAIrC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Feature 043 — packaging-unit snapshot on quote-request lines. The unit name
|
|
4
|
+
* is also appended to `product_name`. Nullable — plain lines have none.
|
|
5
|
+
*/
|
|
6
|
+
export class Migration20260611T140415QuoteRequestsQrItemPackaging extends Migration {
|
|
7
|
+
async up() {
|
|
8
|
+
this.addSql('alter table "quote_request_items" add column "packaging_unit_name" varchar(160) null;');
|
|
9
|
+
this.addSql('alter table "quote_request_items" add column "packaging_unit_base_quantity" integer null;');
|
|
10
|
+
}
|
|
11
|
+
async down() {
|
|
12
|
+
this.addSql('alter table "quote_request_items" drop column "packaging_unit_base_quantity";');
|
|
13
|
+
this.addSql('alter table "quote_request_items" drop column "packaging_unit_name";');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=20260611T140415_quote_requests_qr_item_packaging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260611T140415_quote_requests_qr_item_packaging.js","sourceRoot":"","sources":["../../src/migrations/20260611T140415_quote_requests_qr_item_packaging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,oDAAqD,SAAQ,SAAS;IACxE,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,uFAAuF,CAAC,CAAC;QACrG,IAAI,CAAC,MAAM,CAAC,2FAA2F,CAAC,CAAC;IAC3G,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,+EAA+E,CAAC,CAAC;QAC7F,IAAI,CAAC,MAAM,CAAC,sEAAsE,CAAC,CAAC;IACtF,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Customer-facing business Quote Request ID.
|
|
4
|
+
*
|
|
5
|
+
* Adds `quote_requests.business_id`: a human, business-facing identifier shown
|
|
6
|
+
* to the Customer instead of the internal UUID `id`, mirroring
|
|
7
|
+
* `orders.business_id` (feature 036). Its numeric core comes from a dedicated
|
|
8
|
+
* monotonic sequence (`quote_requests_business_id_seq`); the optional
|
|
9
|
+
* prefix/suffix are admin-configurable via the `quote_requests.business_id.*`
|
|
10
|
+
* settings and applied at creation time by RfqService / RfqAdminService — not
|
|
11
|
+
* here.
|
|
12
|
+
*
|
|
13
|
+
* Strategy:
|
|
14
|
+
* 1. create the sequence,
|
|
15
|
+
* 2. add a nullable `business_id` column,
|
|
16
|
+
* 3. backfill every existing RFQ with the bare sequence value (empty
|
|
17
|
+
* default prefix/suffix),
|
|
18
|
+
* 4. tighten to NOT NULL + UNIQUE.
|
|
19
|
+
*/
|
|
20
|
+
export declare class Migration20260611T140417QuoteRequestsBusinessId extends Migration {
|
|
21
|
+
up(): Promise<void>;
|
|
22
|
+
down(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=20260611T140417_quote_requests_business_id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260611T140417_quote_requests_business_id.d.ts","sourceRoot":"","sources":["../../src/migrations/20260611T140417_quote_requests_business_id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,+CAAgD,SAAQ,SAAS;IAC7D,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAYnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAOrC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Customer-facing business Quote Request ID.
|
|
4
|
+
*
|
|
5
|
+
* Adds `quote_requests.business_id`: a human, business-facing identifier shown
|
|
6
|
+
* to the Customer instead of the internal UUID `id`, mirroring
|
|
7
|
+
* `orders.business_id` (feature 036). Its numeric core comes from a dedicated
|
|
8
|
+
* monotonic sequence (`quote_requests_business_id_seq`); the optional
|
|
9
|
+
* prefix/suffix are admin-configurable via the `quote_requests.business_id.*`
|
|
10
|
+
* settings and applied at creation time by RfqService / RfqAdminService — not
|
|
11
|
+
* here.
|
|
12
|
+
*
|
|
13
|
+
* Strategy:
|
|
14
|
+
* 1. create the sequence,
|
|
15
|
+
* 2. add a nullable `business_id` column,
|
|
16
|
+
* 3. backfill every existing RFQ with the bare sequence value (empty
|
|
17
|
+
* default prefix/suffix),
|
|
18
|
+
* 4. tighten to NOT NULL + UNIQUE.
|
|
19
|
+
*/
|
|
20
|
+
export class Migration20260611T140417QuoteRequestsBusinessId extends Migration {
|
|
21
|
+
async up() {
|
|
22
|
+
this.addSql(`create sequence if not exists "quote_requests_business_id_seq";`);
|
|
23
|
+
this.addSql(`alter table "quote_requests" add column "business_id" varchar(128) null;`);
|
|
24
|
+
this.addSql(`update "quote_requests" set "business_id" = nextval('quote_requests_business_id_seq')::text where "business_id" is null;`);
|
|
25
|
+
this.addSql(`alter table "quote_requests" alter column "business_id" set not null;`);
|
|
26
|
+
this.addSql(`alter table "quote_requests" add constraint "quote_requests_business_id_unique" unique ("business_id");`);
|
|
27
|
+
}
|
|
28
|
+
async down() {
|
|
29
|
+
this.addSql(`alter table "quote_requests" drop constraint "quote_requests_business_id_unique";`);
|
|
30
|
+
this.addSql(`alter table "quote_requests" drop column "business_id";`);
|
|
31
|
+
this.addSql(`drop sequence if exists "quote_requests_business_id_seq";`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=20260611T140417_quote_requests_business_id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260611T140417_quote_requests_business_id.js","sourceRoot":"","sources":["../../src/migrations/20260611T140417_quote_requests_business_id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,+CAAgD,SAAQ,SAAS;IACnE,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,iEAAiE,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,0EAA0E,CAAC,CAAC;QACxF,IAAI,CAAC,MAAM,CACT,0HAA0H,CAC3H,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,uEAAuE,CAAC,CAAC;QACrF,IAAI,CAAC,MAAM,CACT,yGAAyG,CAC1G,CAAC;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CACT,mFAAmF,CACpF,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,2DAA2D,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Backfill the awaiting-acceptance flag for legacy admin-created quotes.
|
|
4
|
+
*
|
|
5
|
+
* Quote Requests created on the customer's behalf (status `Created from admin`)
|
|
6
|
+
* must surface the Accept/Reject controls on the storefront, which gate on
|
|
7
|
+
* `awaiting_customer_revision_acceptance`. The service now sets that flag at
|
|
8
|
+
* creation time (see RfqAdminService.createOnBehalf), but rows created before
|
|
9
|
+
* that fix landed still have the flag at its `false` default, so the customer
|
|
10
|
+
* has no way to act on them.
|
|
11
|
+
*
|
|
12
|
+
* Any RFQ still in `Created from admin` status is genuinely awaiting the
|
|
13
|
+
* customer's decision (acceptance moves it to `Approved`, rejection to
|
|
14
|
+
* `Canceled`), so flipping the flag for exactly those rows is safe and
|
|
15
|
+
* idempotent.
|
|
16
|
+
*/
|
|
17
|
+
export declare class Migration20260617T095510QuoteRequestsBackfillAdminCreatedAwaiting extends Migration {
|
|
18
|
+
up(): Promise<void>;
|
|
19
|
+
down(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts.map
|
package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts","sourceRoot":"","sources":["../../src/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iEAAkE,SAAQ,SAAS;IAC/E,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IASnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAIrC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Backfill the awaiting-acceptance flag for legacy admin-created quotes.
|
|
4
|
+
*
|
|
5
|
+
* Quote Requests created on the customer's behalf (status `Created from admin`)
|
|
6
|
+
* must surface the Accept/Reject controls on the storefront, which gate on
|
|
7
|
+
* `awaiting_customer_revision_acceptance`. The service now sets that flag at
|
|
8
|
+
* creation time (see RfqAdminService.createOnBehalf), but rows created before
|
|
9
|
+
* that fix landed still have the flag at its `false` default, so the customer
|
|
10
|
+
* has no way to act on them.
|
|
11
|
+
*
|
|
12
|
+
* Any RFQ still in `Created from admin` status is genuinely awaiting the
|
|
13
|
+
* customer's decision (acceptance moves it to `Approved`, rejection to
|
|
14
|
+
* `Canceled`), so flipping the flag for exactly those rows is safe and
|
|
15
|
+
* idempotent.
|
|
16
|
+
*/
|
|
17
|
+
export class Migration20260617T095510QuoteRequestsBackfillAdminCreatedAwaiting extends Migration {
|
|
18
|
+
async up() {
|
|
19
|
+
this.addSql(`update "quote_requests"
|
|
20
|
+
set "awaiting_customer_revision_acceptance" = true
|
|
21
|
+
where "status" = 'Created from admin'
|
|
22
|
+
and "awaiting_customer_revision_acceptance" = false;`);
|
|
23
|
+
}
|
|
24
|
+
async down() {
|
|
25
|
+
// Non-reversible data backfill: the original per-row flag value is not
|
|
26
|
+
// recoverable. Leaving the rows as-is on rollback is the safe choice.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=20260617T095510_quote_requests_backfill_admin_created_awaiting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260617T095510_quote_requests_backfill_admin_created_awaiting.js","sourceRoot":"","sources":["../../src/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,iEAAkE,SAAQ,SAAS;IACrF,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CACT;;;8DAGwD,CACzD,CAAC;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,uEAAuE;QACvE,sEAAsE;IACxE,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Feature 055 — Custom Fields Layer. Additive: adds the `custom_field_values`
|
|
4
|
+
* JSONB bag to `quote_requests` so operator-defined fields persist on the host row.
|
|
5
|
+
* The column inherits the host entity's tenant classification (Principle XI);
|
|
6
|
+
* no scoping column is added.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Migration20260718T200342QuoteRequestsQuoteRequestCustomFieldValues extends Migration {
|
|
9
|
+
up(): Promise<void>;
|
|
10
|
+
down(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=20260718T200342_quote_requests_quote_request_custom_field_values.d.ts.map
|
package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260718T200342_quote_requests_quote_request_custom_field_values.d.ts","sourceRoot":"","sources":["../../src/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;GAKG;AACH,qBAAa,kEAAmE,SAAQ,SAAS;IAChF,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAGrC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Feature 055 — Custom Fields Layer. Additive: adds the `custom_field_values`
|
|
4
|
+
* JSONB bag to `quote_requests` so operator-defined fields persist on the host row.
|
|
5
|
+
* The column inherits the host entity's tenant classification (Principle XI);
|
|
6
|
+
* no scoping column is added.
|
|
7
|
+
*/
|
|
8
|
+
export class Migration20260718T200342QuoteRequestsQuoteRequestCustomFieldValues extends Migration {
|
|
9
|
+
async up() {
|
|
10
|
+
this.addSql(`alter table "quote_requests" add column "custom_field_values" jsonb not null default '{}';`);
|
|
11
|
+
}
|
|
12
|
+
async down() {
|
|
13
|
+
this.addSql(`alter table "quote_requests" drop column "custom_field_values";`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=20260718T200342_quote_requests_quote_request_custom_field_values.js.map
|
package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"20260718T200342_quote_requests_quote_request_custom_field_values.js","sourceRoot":"","sources":["../../src/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,OAAO,kEAAmE,SAAQ,SAAS;IACtF,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CACT,4FAA4F,CAC7F,CAAC;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,iEAAiE,CAAC,CAAC;IACjF,CAAC;CACF"}
|