@htlkg/data 0.0.14 → 0.0.16
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/README.md +72 -0
- package/dist/client/index.d.ts +123 -30
- package/dist/client/index.js +75 -1
- package/dist/client/index.js.map +1 -1
- package/dist/hooks/index.d.ts +76 -2
- package/dist/hooks/index.js +224 -6
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +550 -7
- package/dist/index.js.map +1 -1
- package/dist/mutations/index.d.ts +149 -5
- package/dist/mutations/index.js +397 -0
- package/dist/mutations/index.js.map +1 -1
- package/dist/productInstances-CzT3NZKU.d.ts +98 -0
- package/dist/queries/index.d.ts +54 -2
- package/dist/queries/index.js +60 -1
- package/dist/queries/index.js.map +1 -1
- package/dist/server/index.d.ts +47 -0
- package/dist/server/index.js +59 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +5 -1
- package/src/client/index.ts +82 -3
- package/src/client/proxy.ts +170 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useProductInstances.ts +174 -0
- package/src/index.ts +11 -0
- package/src/mutations/accounts.ts +102 -1
- package/src/mutations/brands.ts +102 -1
- package/src/mutations/index.ts +23 -0
- package/src/mutations/productInstances/index.ts +14 -0
- package/src/mutations/productInstances/productInstances.integration.test.ts +621 -0
- package/src/mutations/productInstances/productInstances.test.ts +680 -0
- package/src/mutations/productInstances/productInstances.ts +280 -0
- package/src/mutations/systemSettings.ts +130 -0
- package/src/mutations/users.ts +102 -1
- package/src/queries/index.ts +9 -0
- package/src/queries/systemSettings.ts +115 -0
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/client/index.ts
|
|
2
2
|
import { generateClient as generateDataClient } from "aws-amplify/data";
|
|
3
|
+
import { Amplify } from "aws-amplify";
|
|
3
4
|
|
|
4
5
|
// src/client/server.ts
|
|
5
6
|
import {
|
|
@@ -9,6 +10,54 @@ import { getAmplifyServerContext } from "aws-amplify/adapter-core/internals";
|
|
|
9
10
|
import { createRunWithAmplifyServerContext, createLogger } from "@htlkg/core/amplify-astro-adapter";
|
|
10
11
|
var log = createLogger("server-client");
|
|
11
12
|
|
|
13
|
+
// src/client/proxy.ts
|
|
14
|
+
var DEFAULT_ENDPOINT = "/api/graphql";
|
|
15
|
+
async function mutate(model, operation, data, options) {
|
|
16
|
+
return proxyRequest(model, operation, data, options);
|
|
17
|
+
}
|
|
18
|
+
async function query(model, operation, data, options) {
|
|
19
|
+
return proxyRequest(model, operation, data, options);
|
|
20
|
+
}
|
|
21
|
+
async function proxyRequest(model, operation, data, options) {
|
|
22
|
+
const endpoint = options?.endpoint ?? DEFAULT_ENDPOINT;
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch(endpoint, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json"
|
|
28
|
+
},
|
|
29
|
+
credentials: "include",
|
|
30
|
+
// Important: include cookies
|
|
31
|
+
...options?.fetchOptions,
|
|
32
|
+
body: JSON.stringify({ model, operation, data })
|
|
33
|
+
});
|
|
34
|
+
const result = await response.json();
|
|
35
|
+
if (response.status === 401) {
|
|
36
|
+
console.error("[GraphQL Proxy] Unauthorized - session may have expired");
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("[GraphQL Proxy] Request failed:", error);
|
|
41
|
+
return {
|
|
42
|
+
data: null,
|
|
43
|
+
errors: [
|
|
44
|
+
{
|
|
45
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function hasErrors(response) {
|
|
52
|
+
return !!response.errors && response.errors.length > 0;
|
|
53
|
+
}
|
|
54
|
+
function getErrorMessage(response) {
|
|
55
|
+
if (!response.errors || response.errors.length === 0) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return response.errors[0].message;
|
|
59
|
+
}
|
|
60
|
+
|
|
12
61
|
// src/client/index.ts
|
|
13
62
|
var sharedClientInstance = null;
|
|
14
63
|
function getSharedClient() {
|
|
@@ -23,7 +72,7 @@ function resetSharedClient() {
|
|
|
23
72
|
function generateClient() {
|
|
24
73
|
return generateDataClient();
|
|
25
74
|
}
|
|
26
|
-
function generateServerClient(
|
|
75
|
+
function generateServerClient(_options) {
|
|
27
76
|
const client = generateDataClient();
|
|
28
77
|
return client;
|
|
29
78
|
}
|
|
@@ -385,6 +434,59 @@ async function executePublicQuery(astro, runWithAmplifyServerContext, operation)
|
|
|
385
434
|
return result;
|
|
386
435
|
}
|
|
387
436
|
|
|
437
|
+
// src/queries/systemSettings.ts
|
|
438
|
+
var DEFAULT_SOFT_DELETE_RETENTION_DAYS = 30;
|
|
439
|
+
var SYSTEM_SETTINGS_KEY = "GLOBAL";
|
|
440
|
+
async function getSystemSettings(client) {
|
|
441
|
+
try {
|
|
442
|
+
const { data, errors } = await client.models.SystemSettings.get({
|
|
443
|
+
key: SYSTEM_SETTINGS_KEY
|
|
444
|
+
});
|
|
445
|
+
if (errors) {
|
|
446
|
+
console.error("[getSystemSettings] GraphQL errors:", errors);
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
return data;
|
|
450
|
+
} catch (error) {
|
|
451
|
+
console.error("[getSystemSettings] Error fetching system settings:", error);
|
|
452
|
+
throw error;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
async function getSoftDeleteRetentionDays(client) {
|
|
456
|
+
const settings = await getSystemSettings(client);
|
|
457
|
+
return settings?.softDeleteRetentionDays ?? DEFAULT_SOFT_DELETE_RETENTION_DAYS;
|
|
458
|
+
}
|
|
459
|
+
function checkRestoreEligibility(deletedAt, retentionDays) {
|
|
460
|
+
if (!deletedAt) {
|
|
461
|
+
return {
|
|
462
|
+
canRestore: false,
|
|
463
|
+
daysRemaining: 0,
|
|
464
|
+
daysExpired: 0,
|
|
465
|
+
expiresAt: null
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
const deletedDate = new Date(deletedAt);
|
|
469
|
+
const expiresAt = new Date(deletedDate);
|
|
470
|
+
expiresAt.setDate(expiresAt.getDate() + retentionDays);
|
|
471
|
+
const now = /* @__PURE__ */ new Date();
|
|
472
|
+
const msRemaining = expiresAt.getTime() - now.getTime();
|
|
473
|
+
const daysRemaining = Math.ceil(msRemaining / (1e3 * 60 * 60 * 24));
|
|
474
|
+
if (daysRemaining <= 0) {
|
|
475
|
+
return {
|
|
476
|
+
canRestore: false,
|
|
477
|
+
daysRemaining: 0,
|
|
478
|
+
daysExpired: Math.abs(daysRemaining),
|
|
479
|
+
expiresAt
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
canRestore: true,
|
|
484
|
+
daysRemaining,
|
|
485
|
+
daysExpired: 0,
|
|
486
|
+
expiresAt
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
388
490
|
// src/mutations/brands.ts
|
|
389
491
|
async function createBrand(client, input) {
|
|
390
492
|
try {
|
|
@@ -412,6 +514,53 @@ async function updateBrand(client, input) {
|
|
|
412
514
|
throw error;
|
|
413
515
|
}
|
|
414
516
|
}
|
|
517
|
+
async function softDeleteBrand(client, id, deletedBy) {
|
|
518
|
+
try {
|
|
519
|
+
const { errors } = await client.models.Brand.update({
|
|
520
|
+
id,
|
|
521
|
+
status: "deleted",
|
|
522
|
+
deletedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
523
|
+
deletedBy
|
|
524
|
+
});
|
|
525
|
+
if (errors) {
|
|
526
|
+
console.error("[softDeleteBrand] GraphQL errors:", errors);
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
return true;
|
|
530
|
+
} catch (error) {
|
|
531
|
+
console.error("[softDeleteBrand] Error soft-deleting brand:", error);
|
|
532
|
+
throw error;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function restoreBrand(client, id, retentionDays = DEFAULT_SOFT_DELETE_RETENTION_DAYS) {
|
|
536
|
+
try {
|
|
537
|
+
const { data: brand, errors: getErrors } = await client.models.Brand.get({ id });
|
|
538
|
+
if (getErrors || !brand) {
|
|
539
|
+
console.error("[restoreBrand] Error fetching brand:", getErrors);
|
|
540
|
+
return { success: false, error: "Brand not found" };
|
|
541
|
+
}
|
|
542
|
+
const eligibility = checkRestoreEligibility(brand.deletedAt, retentionDays);
|
|
543
|
+
if (!eligibility.canRestore) {
|
|
544
|
+
const errorMsg = `Cannot restore brand. Retention period of ${retentionDays} days has expired. Item was deleted ${eligibility.daysExpired} days ago.`;
|
|
545
|
+
console.error("[restoreBrand]", errorMsg);
|
|
546
|
+
return { success: false, error: errorMsg };
|
|
547
|
+
}
|
|
548
|
+
const { errors } = await client.models.Brand.update({
|
|
549
|
+
id,
|
|
550
|
+
status: "active",
|
|
551
|
+
deletedAt: null,
|
|
552
|
+
deletedBy: null
|
|
553
|
+
});
|
|
554
|
+
if (errors) {
|
|
555
|
+
console.error("[restoreBrand] GraphQL errors:", errors);
|
|
556
|
+
return { success: false, error: "Failed to restore brand" };
|
|
557
|
+
}
|
|
558
|
+
return { success: true };
|
|
559
|
+
} catch (error) {
|
|
560
|
+
console.error("[restoreBrand] Error restoring brand:", error);
|
|
561
|
+
throw error;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
415
564
|
async function deleteBrand(client, id) {
|
|
416
565
|
try {
|
|
417
566
|
const { errors } = await client.models.Brand.delete({ id });
|
|
@@ -453,6 +602,53 @@ async function updateAccount(client, input) {
|
|
|
453
602
|
throw error;
|
|
454
603
|
}
|
|
455
604
|
}
|
|
605
|
+
async function softDeleteAccount(client, id, deletedBy) {
|
|
606
|
+
try {
|
|
607
|
+
const { errors } = await client.models.Account.update({
|
|
608
|
+
id,
|
|
609
|
+
status: "deleted",
|
|
610
|
+
deletedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
611
|
+
deletedBy
|
|
612
|
+
});
|
|
613
|
+
if (errors) {
|
|
614
|
+
console.error("[softDeleteAccount] GraphQL errors:", errors);
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
return true;
|
|
618
|
+
} catch (error) {
|
|
619
|
+
console.error("[softDeleteAccount] Error soft-deleting account:", error);
|
|
620
|
+
throw error;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
async function restoreAccount(client, id, retentionDays = DEFAULT_SOFT_DELETE_RETENTION_DAYS) {
|
|
624
|
+
try {
|
|
625
|
+
const { data: account, errors: getErrors } = await client.models.Account.get({ id });
|
|
626
|
+
if (getErrors || !account) {
|
|
627
|
+
console.error("[restoreAccount] Error fetching account:", getErrors);
|
|
628
|
+
return { success: false, error: "Account not found" };
|
|
629
|
+
}
|
|
630
|
+
const eligibility = checkRestoreEligibility(account.deletedAt, retentionDays);
|
|
631
|
+
if (!eligibility.canRestore) {
|
|
632
|
+
const errorMsg = `Cannot restore account. Retention period of ${retentionDays} days has expired. Item was deleted ${eligibility.daysExpired} days ago.`;
|
|
633
|
+
console.error("[restoreAccount]", errorMsg);
|
|
634
|
+
return { success: false, error: errorMsg };
|
|
635
|
+
}
|
|
636
|
+
const { errors } = await client.models.Account.update({
|
|
637
|
+
id,
|
|
638
|
+
status: "active",
|
|
639
|
+
deletedAt: null,
|
|
640
|
+
deletedBy: null
|
|
641
|
+
});
|
|
642
|
+
if (errors) {
|
|
643
|
+
console.error("[restoreAccount] GraphQL errors:", errors);
|
|
644
|
+
return { success: false, error: "Failed to restore account" };
|
|
645
|
+
}
|
|
646
|
+
return { success: true };
|
|
647
|
+
} catch (error) {
|
|
648
|
+
console.error("[restoreAccount] Error restoring account:", error);
|
|
649
|
+
throw error;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
456
652
|
async function deleteAccount(client, id) {
|
|
457
653
|
try {
|
|
458
654
|
const { errors } = await client.models.Account.delete({ id });
|
|
@@ -494,6 +690,53 @@ async function updateUser(client, input) {
|
|
|
494
690
|
throw error;
|
|
495
691
|
}
|
|
496
692
|
}
|
|
693
|
+
async function softDeleteUser(client, id, deletedBy) {
|
|
694
|
+
try {
|
|
695
|
+
const { errors } = await client.models.User.update({
|
|
696
|
+
id,
|
|
697
|
+
status: "deleted",
|
|
698
|
+
deletedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
699
|
+
deletedBy
|
|
700
|
+
});
|
|
701
|
+
if (errors) {
|
|
702
|
+
console.error("[softDeleteUser] GraphQL errors:", errors);
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
return true;
|
|
706
|
+
} catch (error) {
|
|
707
|
+
console.error("[softDeleteUser] Error soft-deleting user:", error);
|
|
708
|
+
throw error;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
async function restoreUser(client, id, retentionDays = DEFAULT_SOFT_DELETE_RETENTION_DAYS) {
|
|
712
|
+
try {
|
|
713
|
+
const { data: user, errors: getErrors } = await client.models.User.get({ id });
|
|
714
|
+
if (getErrors || !user) {
|
|
715
|
+
console.error("[restoreUser] Error fetching user:", getErrors);
|
|
716
|
+
return { success: false, error: "User not found" };
|
|
717
|
+
}
|
|
718
|
+
const eligibility = checkRestoreEligibility(user.deletedAt, retentionDays);
|
|
719
|
+
if (!eligibility.canRestore) {
|
|
720
|
+
const errorMsg = `Cannot restore user. Retention period of ${retentionDays} days has expired. Item was deleted ${eligibility.daysExpired} days ago.`;
|
|
721
|
+
console.error("[restoreUser]", errorMsg);
|
|
722
|
+
return { success: false, error: errorMsg };
|
|
723
|
+
}
|
|
724
|
+
const { errors } = await client.models.User.update({
|
|
725
|
+
id,
|
|
726
|
+
status: "active",
|
|
727
|
+
deletedAt: null,
|
|
728
|
+
deletedBy: null
|
|
729
|
+
});
|
|
730
|
+
if (errors) {
|
|
731
|
+
console.error("[restoreUser] GraphQL errors:", errors);
|
|
732
|
+
return { success: false, error: "Failed to restore user" };
|
|
733
|
+
}
|
|
734
|
+
return { success: true };
|
|
735
|
+
} catch (error) {
|
|
736
|
+
console.error("[restoreUser] Error restoring user:", error);
|
|
737
|
+
throw error;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
497
740
|
async function deleteUser(client, id) {
|
|
498
741
|
try {
|
|
499
742
|
const { errors } = await client.models.User.delete({ id });
|
|
@@ -508,6 +751,216 @@ async function deleteUser(client, id) {
|
|
|
508
751
|
}
|
|
509
752
|
}
|
|
510
753
|
|
|
754
|
+
// src/mutations/productInstances/productInstances.ts
|
|
755
|
+
import { getClientUser } from "@htlkg/core/auth";
|
|
756
|
+
import { getCurrentTimestamp } from "@htlkg/core/utils";
|
|
757
|
+
import { AppError } from "@htlkg/core/errors";
|
|
758
|
+
async function getUserIdentifier(fallback = "system") {
|
|
759
|
+
try {
|
|
760
|
+
const user = await getClientUser();
|
|
761
|
+
if (user) {
|
|
762
|
+
return user.email || user.username || fallback;
|
|
763
|
+
}
|
|
764
|
+
return fallback;
|
|
765
|
+
} catch {
|
|
766
|
+
return fallback;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
async function createProductInstance(client, input) {
|
|
770
|
+
try {
|
|
771
|
+
const createInput = {
|
|
772
|
+
productId: input.productId,
|
|
773
|
+
productName: input.productName,
|
|
774
|
+
brandId: input.brandId,
|
|
775
|
+
accountId: input.accountId,
|
|
776
|
+
enabled: input.enabled,
|
|
777
|
+
version: input.version,
|
|
778
|
+
lastUpdated: input.lastUpdated || getCurrentTimestamp(),
|
|
779
|
+
updatedBy: input.updatedBy || await getUserIdentifier()
|
|
780
|
+
};
|
|
781
|
+
if (input.config) {
|
|
782
|
+
createInput.config = JSON.stringify(JSON.parse(JSON.stringify(input.config)));
|
|
783
|
+
}
|
|
784
|
+
console.log("[createProductInstance] Config as string:", createInput.config);
|
|
785
|
+
console.log("[createProductInstance] Config type:", typeof createInput.config);
|
|
786
|
+
const { data, errors } = await client.models.ProductInstance.create(createInput);
|
|
787
|
+
if (errors) {
|
|
788
|
+
console.error("[createProductInstance] GraphQL errors:", errors);
|
|
789
|
+
throw new AppError(
|
|
790
|
+
"Failed to create product instance",
|
|
791
|
+
"PRODUCT_INSTANCE_CREATE_ERROR",
|
|
792
|
+
500,
|
|
793
|
+
{ errors }
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
return data;
|
|
797
|
+
} catch (error) {
|
|
798
|
+
console.error("[createProductInstance] Error creating product instance:", error);
|
|
799
|
+
if (error instanceof AppError) {
|
|
800
|
+
throw error;
|
|
801
|
+
}
|
|
802
|
+
throw new AppError(
|
|
803
|
+
"Failed to create product instance",
|
|
804
|
+
"PRODUCT_INSTANCE_CREATE_ERROR",
|
|
805
|
+
500,
|
|
806
|
+
{ originalError: error }
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
async function updateProductInstance(client, input) {
|
|
811
|
+
try {
|
|
812
|
+
const updateInput = {
|
|
813
|
+
...input,
|
|
814
|
+
lastUpdated: input.lastUpdated || getCurrentTimestamp(),
|
|
815
|
+
updatedBy: input.updatedBy || await getUserIdentifier()
|
|
816
|
+
};
|
|
817
|
+
if (input.config) {
|
|
818
|
+
updateInput.config = JSON.stringify(JSON.parse(JSON.stringify(input.config)));
|
|
819
|
+
}
|
|
820
|
+
const { data, errors } = await client.models.ProductInstance.update(updateInput);
|
|
821
|
+
if (errors) {
|
|
822
|
+
console.error("[updateProductInstance] GraphQL errors:", errors);
|
|
823
|
+
throw new AppError(
|
|
824
|
+
"Failed to update product instance",
|
|
825
|
+
"PRODUCT_INSTANCE_UPDATE_ERROR",
|
|
826
|
+
500,
|
|
827
|
+
{ errors }
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
return data;
|
|
831
|
+
} catch (error) {
|
|
832
|
+
console.error("[updateProductInstance] Error updating product instance:", error);
|
|
833
|
+
if (error instanceof AppError) {
|
|
834
|
+
throw error;
|
|
835
|
+
}
|
|
836
|
+
throw new AppError(
|
|
837
|
+
"Failed to update product instance",
|
|
838
|
+
"PRODUCT_INSTANCE_UPDATE_ERROR",
|
|
839
|
+
500,
|
|
840
|
+
{ originalError: error }
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
async function deleteProductInstance(client, id) {
|
|
845
|
+
try {
|
|
846
|
+
const { errors } = await client.models.ProductInstance.delete({ id });
|
|
847
|
+
if (errors) {
|
|
848
|
+
console.error("[deleteProductInstance] GraphQL errors:", errors);
|
|
849
|
+
throw new AppError(
|
|
850
|
+
"Failed to delete product instance",
|
|
851
|
+
"PRODUCT_INSTANCE_DELETE_ERROR",
|
|
852
|
+
500,
|
|
853
|
+
{ errors }
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
return true;
|
|
857
|
+
} catch (error) {
|
|
858
|
+
console.error("[deleteProductInstance] Error deleting product instance:", error);
|
|
859
|
+
if (error instanceof AppError) {
|
|
860
|
+
throw error;
|
|
861
|
+
}
|
|
862
|
+
throw new AppError(
|
|
863
|
+
"Failed to delete product instance",
|
|
864
|
+
"PRODUCT_INSTANCE_DELETE_ERROR",
|
|
865
|
+
500,
|
|
866
|
+
{ originalError: error }
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
async function toggleProductInstanceEnabled(client, id, enabled) {
|
|
871
|
+
try {
|
|
872
|
+
const { data, errors } = await client.models.ProductInstance.update({
|
|
873
|
+
id,
|
|
874
|
+
enabled,
|
|
875
|
+
lastUpdated: getCurrentTimestamp(),
|
|
876
|
+
updatedBy: await getUserIdentifier()
|
|
877
|
+
});
|
|
878
|
+
if (errors) {
|
|
879
|
+
console.error("[toggleProductInstanceEnabled] GraphQL errors:", errors);
|
|
880
|
+
throw new AppError(
|
|
881
|
+
"Failed to toggle product instance",
|
|
882
|
+
"PRODUCT_INSTANCE_TOGGLE_ERROR",
|
|
883
|
+
500,
|
|
884
|
+
{ errors }
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
return data;
|
|
888
|
+
} catch (error) {
|
|
889
|
+
console.error("[toggleProductInstanceEnabled] Error toggling product instance:", error);
|
|
890
|
+
if (error instanceof AppError) {
|
|
891
|
+
throw error;
|
|
892
|
+
}
|
|
893
|
+
throw new AppError(
|
|
894
|
+
"Failed to toggle product instance",
|
|
895
|
+
"PRODUCT_INSTANCE_TOGGLE_ERROR",
|
|
896
|
+
500,
|
|
897
|
+
{ originalError: error }
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/mutations/systemSettings.ts
|
|
903
|
+
async function updateSystemSettings(client, input) {
|
|
904
|
+
try {
|
|
905
|
+
if (input.softDeleteRetentionDays < 1 || input.softDeleteRetentionDays > 365) {
|
|
906
|
+
console.error(
|
|
907
|
+
"[updateSystemSettings] Invalid retention days. Must be between 1 and 365."
|
|
908
|
+
);
|
|
909
|
+
return null;
|
|
910
|
+
}
|
|
911
|
+
const { data: existing } = await client.models.SystemSettings.get({
|
|
912
|
+
key: SYSTEM_SETTINGS_KEY
|
|
913
|
+
});
|
|
914
|
+
const settingsData = {
|
|
915
|
+
key: SYSTEM_SETTINGS_KEY,
|
|
916
|
+
softDeleteRetentionDays: input.softDeleteRetentionDays,
|
|
917
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
918
|
+
updatedBy: input.updatedBy
|
|
919
|
+
};
|
|
920
|
+
let result;
|
|
921
|
+
if (existing) {
|
|
922
|
+
result = await client.models.SystemSettings.update(settingsData);
|
|
923
|
+
} else {
|
|
924
|
+
result = await client.models.SystemSettings.create(settingsData);
|
|
925
|
+
}
|
|
926
|
+
if (result.errors) {
|
|
927
|
+
console.error("[updateSystemSettings] GraphQL errors:", result.errors);
|
|
928
|
+
return null;
|
|
929
|
+
}
|
|
930
|
+
return result.data;
|
|
931
|
+
} catch (error) {
|
|
932
|
+
console.error("[updateSystemSettings] Error updating system settings:", error);
|
|
933
|
+
throw error;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
async function initializeSystemSettings(client, initializedBy) {
|
|
937
|
+
try {
|
|
938
|
+
const { data: existing } = await client.models.SystemSettings.get({
|
|
939
|
+
key: SYSTEM_SETTINGS_KEY
|
|
940
|
+
});
|
|
941
|
+
if (existing) {
|
|
942
|
+
return existing;
|
|
943
|
+
}
|
|
944
|
+
const { data, errors } = await client.models.SystemSettings.create({
|
|
945
|
+
key: SYSTEM_SETTINGS_KEY,
|
|
946
|
+
softDeleteRetentionDays: DEFAULT_SOFT_DELETE_RETENTION_DAYS,
|
|
947
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
948
|
+
updatedBy: initializedBy
|
|
949
|
+
});
|
|
950
|
+
if (errors) {
|
|
951
|
+
console.error("[initializeSystemSettings] GraphQL errors:", errors);
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
return data;
|
|
955
|
+
} catch (error) {
|
|
956
|
+
console.error(
|
|
957
|
+
"[initializeSystemSettings] Error initializing system settings:",
|
|
958
|
+
error
|
|
959
|
+
);
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
511
964
|
// src/hooks/createDataHook.ts
|
|
512
965
|
import { ref, computed, onMounted } from "vue";
|
|
513
966
|
function createDataHook(config) {
|
|
@@ -516,7 +969,7 @@ function createDataHook(config) {
|
|
|
516
969
|
defaultLimit,
|
|
517
970
|
selectionSet,
|
|
518
971
|
transform,
|
|
519
|
-
buildFilter:
|
|
972
|
+
buildFilter: buildFilter5,
|
|
520
973
|
computedProperties,
|
|
521
974
|
dataPropertyName = "data"
|
|
522
975
|
} = config;
|
|
@@ -526,12 +979,12 @@ function createDataHook(config) {
|
|
|
526
979
|
const loading = ref(false);
|
|
527
980
|
const error = ref(null);
|
|
528
981
|
const getFilter = () => {
|
|
529
|
-
if (
|
|
530
|
-
return
|
|
982
|
+
if (buildFilter5) {
|
|
983
|
+
return buildFilter5(options);
|
|
531
984
|
}
|
|
532
985
|
return baseFilter && Object.keys(baseFilter).length > 0 ? baseFilter : void 0;
|
|
533
986
|
};
|
|
534
|
-
async function
|
|
987
|
+
async function fetch2() {
|
|
535
988
|
loading.value = true;
|
|
536
989
|
error.value = null;
|
|
537
990
|
try {
|
|
@@ -564,14 +1017,14 @@ function createDataHook(config) {
|
|
|
564
1017
|
}
|
|
565
1018
|
if (autoFetch) {
|
|
566
1019
|
onMounted(() => {
|
|
567
|
-
|
|
1020
|
+
fetch2();
|
|
568
1021
|
});
|
|
569
1022
|
}
|
|
570
1023
|
const result = {
|
|
571
1024
|
data,
|
|
572
1025
|
loading,
|
|
573
1026
|
error,
|
|
574
|
-
refetch:
|
|
1027
|
+
refetch: fetch2,
|
|
575
1028
|
computed: computedRefs
|
|
576
1029
|
};
|
|
577
1030
|
if (dataPropertyName !== "data") {
|
|
@@ -682,6 +1135,74 @@ function useProducts(options = {}) {
|
|
|
682
1135
|
};
|
|
683
1136
|
}
|
|
684
1137
|
|
|
1138
|
+
// src/hooks/useProductInstances.ts
|
|
1139
|
+
function buildFilter4(options) {
|
|
1140
|
+
let filter = options.filter || {};
|
|
1141
|
+
if (options.brandId) {
|
|
1142
|
+
filter = { ...filter, brandId: { eq: options.brandId } };
|
|
1143
|
+
}
|
|
1144
|
+
if (options.accountId) {
|
|
1145
|
+
filter = { ...filter, accountId: { eq: options.accountId } };
|
|
1146
|
+
}
|
|
1147
|
+
if (options.productId) {
|
|
1148
|
+
filter = { ...filter, productId: { eq: options.productId } };
|
|
1149
|
+
}
|
|
1150
|
+
if (options.enabledOnly) {
|
|
1151
|
+
filter = { ...filter, enabled: { eq: true } };
|
|
1152
|
+
}
|
|
1153
|
+
return Object.keys(filter).length > 0 ? filter : void 0;
|
|
1154
|
+
}
|
|
1155
|
+
var useProductInstancesInternal = createDataHook({
|
|
1156
|
+
model: "ProductInstance",
|
|
1157
|
+
dataPropertyName: "instances",
|
|
1158
|
+
buildFilter: buildFilter4,
|
|
1159
|
+
computedProperties: {
|
|
1160
|
+
enabledInstances: (instances) => instances.filter((i) => i.enabled)
|
|
1161
|
+
}
|
|
1162
|
+
});
|
|
1163
|
+
function useProductInstances(options = {}) {
|
|
1164
|
+
const result = useProductInstancesInternal(options);
|
|
1165
|
+
async function createInstance(input) {
|
|
1166
|
+
const client = getSharedClient();
|
|
1167
|
+
const instance = await createProductInstance(client, input);
|
|
1168
|
+
if (!instance) {
|
|
1169
|
+
throw new Error("Failed to create product instance");
|
|
1170
|
+
}
|
|
1171
|
+
return instance;
|
|
1172
|
+
}
|
|
1173
|
+
async function updateInstance(input) {
|
|
1174
|
+
const client = getSharedClient();
|
|
1175
|
+
const instance = await updateProductInstance(client, input);
|
|
1176
|
+
if (!instance) {
|
|
1177
|
+
throw new Error("Failed to update product instance");
|
|
1178
|
+
}
|
|
1179
|
+
return instance;
|
|
1180
|
+
}
|
|
1181
|
+
async function deleteInstance(id) {
|
|
1182
|
+
const client = getSharedClient();
|
|
1183
|
+
return deleteProductInstance(client, id);
|
|
1184
|
+
}
|
|
1185
|
+
async function toggleEnabled(id, enabled) {
|
|
1186
|
+
const client = getSharedClient();
|
|
1187
|
+
const instance = await toggleProductInstanceEnabled(client, id, enabled);
|
|
1188
|
+
if (!instance) {
|
|
1189
|
+
throw new Error("Failed to toggle product instance");
|
|
1190
|
+
}
|
|
1191
|
+
return instance;
|
|
1192
|
+
}
|
|
1193
|
+
return {
|
|
1194
|
+
instances: result.instances,
|
|
1195
|
+
enabledInstances: result.enabledInstances,
|
|
1196
|
+
loading: result.loading,
|
|
1197
|
+
error: result.error,
|
|
1198
|
+
refetch: result.refetch,
|
|
1199
|
+
createInstance,
|
|
1200
|
+
updateInstance,
|
|
1201
|
+
deleteInstance,
|
|
1202
|
+
toggleEnabled
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
|
|
685
1206
|
// ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js
|
|
686
1207
|
var clean = /* @__PURE__ */ Symbol("clean");
|
|
687
1208
|
|
|
@@ -785,15 +1306,20 @@ function createSingleStore(shared, name, defaultValue) {
|
|
|
785
1306
|
return shared(name, atom(defaultValue));
|
|
786
1307
|
}
|
|
787
1308
|
export {
|
|
1309
|
+
DEFAULT_SOFT_DELETE_RETENTION_DAYS,
|
|
1310
|
+
SYSTEM_SETTINGS_KEY,
|
|
1311
|
+
checkRestoreEligibility,
|
|
788
1312
|
createAccount,
|
|
789
1313
|
createBrand,
|
|
790
1314
|
createDataHook,
|
|
1315
|
+
createProductInstance,
|
|
791
1316
|
createResourceStores,
|
|
792
1317
|
createSingleStore,
|
|
793
1318
|
createStore,
|
|
794
1319
|
createUser,
|
|
795
1320
|
deleteAccount,
|
|
796
1321
|
deleteBrand,
|
|
1322
|
+
deleteProductInstance,
|
|
797
1323
|
deleteUser,
|
|
798
1324
|
executePublicQuery,
|
|
799
1325
|
executeServerQuery,
|
|
@@ -803,12 +1329,17 @@ export {
|
|
|
803
1329
|
getAccountWithBrands,
|
|
804
1330
|
getBrand,
|
|
805
1331
|
getBrandWithProducts,
|
|
1332
|
+
getErrorMessage,
|
|
806
1333
|
getProduct,
|
|
807
1334
|
getProductInstance,
|
|
808
1335
|
getSharedClient,
|
|
1336
|
+
getSoftDeleteRetentionDays,
|
|
1337
|
+
getSystemSettings,
|
|
809
1338
|
getUser,
|
|
810
1339
|
getUserByCognitoId,
|
|
811
1340
|
getUserByEmail,
|
|
1341
|
+
hasErrors,
|
|
1342
|
+
initializeSystemSettings,
|
|
812
1343
|
listAccounts,
|
|
813
1344
|
listActiveBrands,
|
|
814
1345
|
listActiveProducts,
|
|
@@ -821,13 +1352,25 @@ export {
|
|
|
821
1352
|
listProducts,
|
|
822
1353
|
listUsers,
|
|
823
1354
|
listUsersByAccount,
|
|
1355
|
+
mutate,
|
|
1356
|
+
query,
|
|
824
1357
|
resetSharedClient as resetClientInstance,
|
|
825
1358
|
resetSharedClient,
|
|
1359
|
+
restoreAccount,
|
|
1360
|
+
restoreBrand,
|
|
1361
|
+
restoreUser,
|
|
1362
|
+
softDeleteAccount,
|
|
1363
|
+
softDeleteBrand,
|
|
1364
|
+
softDeleteUser,
|
|
1365
|
+
toggleProductInstanceEnabled,
|
|
826
1366
|
updateAccount,
|
|
827
1367
|
updateBrand,
|
|
1368
|
+
updateProductInstance,
|
|
1369
|
+
updateSystemSettings,
|
|
828
1370
|
updateUser,
|
|
829
1371
|
useAccounts,
|
|
830
1372
|
useBrands,
|
|
1373
|
+
useProductInstances,
|
|
831
1374
|
useProducts,
|
|
832
1375
|
useUsers
|
|
833
1376
|
};
|