@devlider001/washlab-backend 1.0.4 → 1.0.6

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.
Files changed (78) hide show
  1. package/convex/_generated/api.d.ts +2 -0
  2. package/convex/admin.d.ts +1 -1
  3. package/convex/audit.d.ts +39 -0
  4. package/convex/customers.d.ts +12 -5
  5. package/convex/lib/auth.d.ts +24 -1
  6. package/convex/notifications.d.ts +170 -0
  7. package/convex/schema.d.ts +53 -2
  8. package/dist/convex/admin.d.ts +377 -0
  9. package/dist/convex/admin.d.ts.map +1 -0
  10. package/dist/convex/admin.js +959 -0
  11. package/dist/convex/admin.js.map +1 -0
  12. package/dist/convex/analytics.d.ts +87 -0
  13. package/dist/convex/analytics.d.ts.map +1 -0
  14. package/dist/convex/analytics.js +361 -0
  15. package/dist/convex/analytics.js.map +1 -0
  16. package/dist/convex/attendants.d.ts +140 -0
  17. package/dist/convex/attendants.d.ts.map +1 -0
  18. package/dist/convex/attendants.js +337 -0
  19. package/dist/convex/attendants.js.map +1 -0
  20. package/dist/convex/audit.d.ts +158 -0
  21. package/dist/convex/audit.d.ts.map +1 -0
  22. package/dist/convex/audit.js +184 -0
  23. package/dist/convex/audit.js.map +1 -0
  24. package/dist/convex/clerk.d.ts +53 -0
  25. package/dist/convex/clerk.d.ts.map +1 -0
  26. package/dist/convex/clerk.js +316 -0
  27. package/dist/convex/clerk.js.map +1 -0
  28. package/dist/convex/customers.d.ts +224 -0
  29. package/dist/convex/customers.d.ts.map +1 -0
  30. package/dist/convex/customers.js +504 -0
  31. package/dist/convex/customers.js.map +1 -0
  32. package/dist/convex/http.d.ts +3 -0
  33. package/dist/convex/http.d.ts.map +1 -0
  34. package/dist/convex/http.js +115 -0
  35. package/dist/convex/http.js.map +1 -0
  36. package/dist/convex/lib/audit.d.ts +36 -0
  37. package/dist/convex/lib/audit.d.ts.map +1 -0
  38. package/dist/convex/lib/audit.js +59 -0
  39. package/dist/convex/lib/audit.js.map +1 -0
  40. package/dist/convex/lib/auth.d.ts +96 -0
  41. package/dist/convex/lib/auth.d.ts.map +1 -0
  42. package/dist/convex/lib/auth.js +94 -0
  43. package/dist/convex/lib/auth.js.map +1 -0
  44. package/dist/convex/lib/utils.d.ts +38 -0
  45. package/dist/convex/lib/utils.d.ts.map +1 -0
  46. package/dist/convex/lib/utils.js +71 -0
  47. package/dist/convex/lib/utils.js.map +1 -0
  48. package/dist/convex/loyalty.d.ts +82 -0
  49. package/dist/convex/loyalty.d.ts.map +1 -0
  50. package/dist/convex/loyalty.js +286 -0
  51. package/dist/convex/loyalty.js.map +1 -0
  52. package/dist/convex/orders.d.ts +326 -0
  53. package/dist/convex/orders.d.ts.map +1 -0
  54. package/dist/convex/orders.js +570 -0
  55. package/dist/convex/orders.js.map +1 -0
  56. package/dist/convex/payments.d.ts +134 -0
  57. package/dist/convex/payments.d.ts.map +1 -0
  58. package/dist/convex/payments.js +360 -0
  59. package/dist/convex/payments.js.map +1 -0
  60. package/dist/convex/resources.d.ts +119 -0
  61. package/dist/convex/resources.d.ts.map +1 -0
  62. package/dist/convex/resources.js +283 -0
  63. package/dist/convex/resources.js.map +1 -0
  64. package/dist/convex/schema.d.ts +450 -0
  65. package/dist/convex/schema.d.ts.map +1 -0
  66. package/dist/convex/schema.js +347 -0
  67. package/dist/convex/schema.js.map +1 -0
  68. package/dist/convex/vouchers.d.ts +187 -0
  69. package/dist/convex/vouchers.d.ts.map +1 -0
  70. package/dist/convex/vouchers.js +464 -0
  71. package/dist/convex/vouchers.js.map +1 -0
  72. package/dist/src/index.d.ts +9 -0
  73. package/dist/src/index.d.ts.map +1 -0
  74. package/dist/src/index.js +9 -0
  75. package/dist/src/index.js.map +1 -0
  76. package/package.json +5 -3
  77. package/convex/_generated/api.js +0 -23
  78. package/convex/_generated/server.js +0 -93
@@ -0,0 +1,36 @@
1
+ import { MutationCtx } from "../_generated/server";
2
+ import { Id } from "../_generated/dataModel";
3
+ /**
4
+ * Audit logging utilities
5
+ *
6
+ * These functions create audit log entries for all important actions
7
+ * to maintain accountability and compliance.
8
+ */
9
+ interface AuditLogParams {
10
+ ctx: MutationCtx;
11
+ actorId: string;
12
+ actorType: "customer" | "attendant" | "admin";
13
+ actorRole: string;
14
+ action: string;
15
+ entityType: string;
16
+ entityId?: string;
17
+ branchId?: Id<"branches">;
18
+ deviceId?: string;
19
+ details?: string;
20
+ oldValue?: string;
21
+ newValue?: string;
22
+ }
23
+ /**
24
+ * Create an audit log entry
25
+ */
26
+ export declare function createAuditLog({ ctx, actorId, actorType, actorRole, action, entityType, entityId, branchId, deviceId, details, oldValue, newValue, }: AuditLogParams): Promise<Id<"auditLogs">>;
27
+ /**
28
+ * Create audit log for order status change
29
+ */
30
+ export declare function logOrderStatusChange(ctx: MutationCtx, orderId: Id<"orders">, attendantId: Id<"attendants">, oldStatus: string, newStatus: string, branchId: Id<"branches">, notes?: string): Promise<Id<"auditLogs">>;
31
+ /**
32
+ * Create audit log for payment
33
+ */
34
+ export declare function logPayment(ctx: MutationCtx, paymentId: Id<"payments">, orderId: Id<"orders">, customerId: Id<"users">, action: string, amount: number, paymentMethod: string, branchId?: Id<"branches">, attendantId?: Id<"attendants">, reason?: string): Promise<Id<"auditLogs">>;
35
+ export {};
36
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../convex/lib/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAE7C;;;;;GAKG;AAEH,UAAU,cAAc;IACtB,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,EACnC,GAAG,EACH,OAAO,EACP,SAAS,EACT,SAAS,EACT,MAAM,EACN,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,GAAG,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAe3C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,EACrB,WAAW,EAAE,EAAE,CAAC,YAAY,CAAC,EAC7B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,EACxB,KAAK,CAAC,EAAE,MAAM,4BAcf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,EACzB,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,EACrB,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,EACvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EACzB,WAAW,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAC9B,MAAM,CAAC,EAAE,MAAM,4BAmBhB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Create an audit log entry
3
+ */
4
+ export async function createAuditLog({ ctx, actorId, actorType, actorRole, action, entityType, entityId, branchId, deviceId, details, oldValue, newValue, }) {
5
+ return await ctx.db.insert("auditLogs", {
6
+ actorId,
7
+ actorType,
8
+ actorRole,
9
+ action,
10
+ entityType,
11
+ entityId,
12
+ branchId,
13
+ deviceId,
14
+ details: details,
15
+ oldValue: oldValue,
16
+ newValue: newValue,
17
+ timestamp: Date.now(),
18
+ });
19
+ }
20
+ /**
21
+ * Create audit log for order status change
22
+ */
23
+ export async function logOrderStatusChange(ctx, orderId, attendantId, oldStatus, newStatus, branchId, notes) {
24
+ return await createAuditLog({
25
+ ctx,
26
+ actorId: attendantId,
27
+ actorType: "attendant",
28
+ actorRole: "attendant",
29
+ action: "order.status_changed",
30
+ entityType: "order",
31
+ entityId: orderId,
32
+ branchId,
33
+ oldValue: JSON.stringify({ status: oldStatus }),
34
+ newValue: JSON.stringify({ status: newStatus, notes }),
35
+ });
36
+ }
37
+ /**
38
+ * Create audit log for payment
39
+ */
40
+ export async function logPayment(ctx, paymentId, orderId, customerId, action, amount, paymentMethod, branchId, attendantId, reason) {
41
+ return await createAuditLog({
42
+ ctx,
43
+ actorId: attendantId || customerId,
44
+ actorType: attendantId ? "attendant" : "customer",
45
+ actorRole: attendantId ? "attendant" : "customer",
46
+ action,
47
+ entityType: "payment",
48
+ entityId: paymentId,
49
+ branchId,
50
+ details: JSON.stringify({
51
+ orderId,
52
+ customerId,
53
+ amount,
54
+ paymentMethod,
55
+ reason,
56
+ }),
57
+ });
58
+ }
59
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../convex/lib/audit.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,GAAG,EACH,OAAO,EACP,SAAS,EACT,SAAS,EACT,MAAM,EACN,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,GACO;IACf,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;QACtC,OAAO;QACP,SAAS;QACT,SAAS;QACT,MAAM;QACN,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAgB,EAChB,OAAqB,EACrB,WAA6B,EAC7B,SAAiB,EACjB,SAAiB,EACjB,QAAwB,EACxB,KAAc;IAEd,OAAO,MAAM,cAAc,CAAC;QAC1B,GAAG;QACH,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,WAAW;QACtB,SAAS,EAAE,WAAW;QACtB,MAAM,EAAE,sBAAsB;QAC9B,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,OAAO;QACjB,QAAQ;QACR,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/C,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAgB,EAChB,SAAyB,EACzB,OAAqB,EACrB,UAAuB,EACvB,MAAc,EACd,MAAc,EACd,aAAqB,EACrB,QAAyB,EACzB,WAA8B,EAC9B,MAAe;IAEf,OAAO,MAAM,cAAc,CAAC;QAC1B,GAAG;QACH,OAAO,EAAE,WAAW,IAAI,UAAU;QAClC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU;QACjD,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU;QACjD,MAAM;QACN,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS;QACnB,QAAQ;QACR,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;YACtB,OAAO;YACP,UAAU;YACV,MAAM;YACN,aAAa;YACb,MAAM;SACP,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { QueryCtx, MutationCtx } from "../_generated/server";
2
+ import { Id } from "../_generated/dataModel";
3
+ /**
4
+ * Get the current authenticated Clerk user identity
5
+ * @throws Error if user is not authenticated
6
+ */
7
+ export declare function getClerkIdentity(ctx: QueryCtx | MutationCtx): Promise<import("convex/server").UserIdentity>;
8
+ /**
9
+ * Get current customer user from Clerk identity
10
+ * @throws Error if user is not authenticated or not found
11
+ */
12
+ export declare function getCurrentCustomer(ctx: QueryCtx | MutationCtx): Promise<{
13
+ _id: import("convex/values").GenericId<"users">;
14
+ _creationTime: number;
15
+ email?: string | undefined;
16
+ clerkUserId?: string | undefined;
17
+ statusNote?: string | undefined;
18
+ statusChangedBy?: import("convex/values").GenericId<"admins"> | undefined;
19
+ statusChangedAt?: number | undefined;
20
+ lastLoginAt?: number | undefined;
21
+ preferredBranchId?: import("convex/values").GenericId<"branches"> | undefined;
22
+ phoneNumber: string;
23
+ name: string;
24
+ isRegistered: boolean;
25
+ isVerified: boolean;
26
+ status: "active" | "blocked" | "suspended" | "restricted";
27
+ createdAt: number;
28
+ isDeleted: boolean;
29
+ }>;
30
+ /**
31
+ * Get current attendant from Clerk identity
32
+ * @throws Error if user is not authenticated or not found
33
+ */
34
+ export declare function getCurrentAttendant(ctx: QueryCtx | MutationCtx): Promise<{
35
+ _id: import("convex/values").GenericId<"attendants">;
36
+ _creationTime: number;
37
+ lastLoginAt?: number | undefined;
38
+ passcode?: string | undefined;
39
+ phoneNumber: string;
40
+ email: string;
41
+ name: string;
42
+ clerkUserId: string;
43
+ createdAt: number;
44
+ isDeleted: boolean;
45
+ branchId: import("convex/values").GenericId<"branches">;
46
+ isActive: boolean;
47
+ }>;
48
+ /**
49
+ * Get current admin from Clerk identity
50
+ * @throws Error if user is not authenticated or not found
51
+ */
52
+ export declare function getCurrentAdmin(ctx: QueryCtx | MutationCtx): Promise<{
53
+ _id: import("convex/values").GenericId<"admins">;
54
+ _creationTime: number;
55
+ lastLoginAt?: number | undefined;
56
+ email: string;
57
+ name: string;
58
+ clerkUserId: string;
59
+ createdAt: number;
60
+ isDeleted: boolean;
61
+ role: "super_admin" | "admin";
62
+ }>;
63
+ /**
64
+ * Get current admin with super admin role check
65
+ * @throws Error if user is not authenticated, not found, or not super admin
66
+ */
67
+ export declare function getSuperAdmin(ctx: QueryCtx | MutationCtx): Promise<{
68
+ _id: import("convex/values").GenericId<"admins">;
69
+ _creationTime: number;
70
+ lastLoginAt?: number | undefined;
71
+ email: string;
72
+ name: string;
73
+ clerkUserId: string;
74
+ createdAt: number;
75
+ isDeleted: boolean;
76
+ role: "super_admin" | "admin";
77
+ }>;
78
+ /**
79
+ * Verify attendant is assigned to the specified branch
80
+ * @throws Error if attendant is not assigned to the branch
81
+ */
82
+ export declare function verifyAttendantBranch(ctx: QueryCtx | MutationCtx, attendantId: Id<"attendants">, branchId: Id<"branches">): Promise<{
83
+ _id: import("convex/values").GenericId<"attendants">;
84
+ _creationTime: number;
85
+ lastLoginAt?: number | undefined;
86
+ passcode?: string | undefined;
87
+ phoneNumber: string;
88
+ email: string;
89
+ name: string;
90
+ clerkUserId: string;
91
+ createdAt: number;
92
+ isDeleted: boolean;
93
+ branchId: import("convex/values").GenericId<"branches">;
94
+ isActive: boolean;
95
+ }>;
96
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../convex/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAG7C;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,iDAMjE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW;;;;;;;;;;;;;;;;;GAkBnE;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW;;;;;;;;;;;;;GAkBpE;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW;;;;;;;;;;GAkBhE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW;;;;;;;;;;GAQ9D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,QAAQ,GAAG,WAAW,EAC3B,WAAW,EAAE,EAAE,CAAC,YAAY,CAAC,EAC7B,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC;;;;;;;;;;;;;GAYzB"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Get the current authenticated Clerk user identity
3
+ * @throws Error if user is not authenticated
4
+ */
5
+ export async function getClerkIdentity(ctx) {
6
+ const identity = await ctx.auth.getUserIdentity();
7
+ if (!identity) {
8
+ throw new Error("Authentication required");
9
+ }
10
+ return identity;
11
+ }
12
+ /**
13
+ * Get current customer user from Clerk identity
14
+ * @throws Error if user is not authenticated or not found
15
+ */
16
+ export async function getCurrentCustomer(ctx) {
17
+ const identity = await getClerkIdentity(ctx);
18
+ const clerkUserId = identity.subject;
19
+ const user = await ctx.db
20
+ .query("users")
21
+ .withIndex("by_clerk_user", (q) => q.eq("clerkUserId", clerkUserId))
22
+ .first();
23
+ if (!user) {
24
+ throw new Error("Customer not found. Please complete registration.");
25
+ }
26
+ if (user.isDeleted) {
27
+ throw new Error("Customer account has been deleted");
28
+ }
29
+ return user;
30
+ }
31
+ /**
32
+ * Get current attendant from Clerk identity
33
+ * @throws Error if user is not authenticated or not found
34
+ */
35
+ export async function getCurrentAttendant(ctx) {
36
+ const identity = await getClerkIdentity(ctx);
37
+ const clerkUserId = identity.subject;
38
+ const attendant = await ctx.db
39
+ .query("attendants")
40
+ .withIndex("by_clerk_user", (q) => q.eq("clerkUserId", clerkUserId))
41
+ .first();
42
+ if (!attendant) {
43
+ throw new Error("Attendant not found");
44
+ }
45
+ if (attendant.isDeleted || !attendant.isActive) {
46
+ throw new Error("Attendant account is inactive");
47
+ }
48
+ return attendant;
49
+ }
50
+ /**
51
+ * Get current admin from Clerk identity
52
+ * @throws Error if user is not authenticated or not found
53
+ */
54
+ export async function getCurrentAdmin(ctx) {
55
+ const identity = await getClerkIdentity(ctx);
56
+ const clerkUserId = identity.subject;
57
+ const admin = await ctx.db
58
+ .query("admins")
59
+ .withIndex("by_clerk_user", (q) => q.eq("clerkUserId", clerkUserId))
60
+ .first();
61
+ if (!admin) {
62
+ throw new Error("Admin not found");
63
+ }
64
+ if (admin.isDeleted) {
65
+ throw new Error("Admin account has been deleted");
66
+ }
67
+ return admin;
68
+ }
69
+ /**
70
+ * Get current admin with super admin role check
71
+ * @throws Error if user is not authenticated, not found, or not super admin
72
+ */
73
+ export async function getSuperAdmin(ctx) {
74
+ const admin = await getCurrentAdmin(ctx);
75
+ if (admin.role !== "super_admin") {
76
+ throw new Error("Super admin access required");
77
+ }
78
+ return admin;
79
+ }
80
+ /**
81
+ * Verify attendant is assigned to the specified branch
82
+ * @throws Error if attendant is not assigned to the branch
83
+ */
84
+ export async function verifyAttendantBranch(ctx, attendantId, branchId) {
85
+ const attendant = await ctx.db.get(attendantId);
86
+ if (!attendant || attendant.isDeleted) {
87
+ throw new Error("Attendant not found");
88
+ }
89
+ if (attendant.branchId !== branchId) {
90
+ throw new Error("Attendant is not assigned to this branch");
91
+ }
92
+ return attendant;
93
+ }
94
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../convex/lib/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Utility functions for common operations
3
+ */
4
+ /**
5
+ * Generate unique order number
6
+ * Format: WL-YYYY-XXXXXX (where XXXXXX is sequential)
7
+ */
8
+ export declare function generateOrderNumber(): string;
9
+ /**
10
+ * Calculate order price based on weight and branch pricing
11
+ */
12
+ export declare function calculateOrderPrice(weight: number, pricingPerKg: number, deliveryFee: number, isDelivery: boolean): {
13
+ basePrice: number;
14
+ deliveryFee: number;
15
+ totalPrice: number;
16
+ };
17
+ /**
18
+ * Calculate service price based on service type
19
+ * Service pricing:
20
+ * - wash_only: ₵25/load
21
+ * - wash_and_dry: ₵50/load
22
+ * - dry_only: ₵25/load
23
+ */
24
+ export declare function calculateServicePrice(serviceType: "wash_only" | "wash_and_dry" | "dry_only", estimatedWeight: number, estimatedLoads: number, pricingPerKg: number, // Fallback pricing per kg
25
+ deliveryFee: number, isDelivery: boolean): {
26
+ basePrice: number;
27
+ deliveryFee: number;
28
+ totalPrice: number;
29
+ };
30
+ /**
31
+ * Format date to YYYY-MM-DD string
32
+ */
33
+ export declare function formatDate(date: Date): string;
34
+ /**
35
+ * Get current timestamp in milliseconds
36
+ */
37
+ export declare function getCurrentTimestamp(): number;
38
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../convex/lib/utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAM5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,GAClB;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAUA;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,WAAW,GAAG,cAAc,GAAG,UAAU,EACtD,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EAAE,0BAA0B;AAChD,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,GAClB;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAsBA;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAK7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Utility functions for common operations
3
+ */
4
+ /**
5
+ * Generate unique order number
6
+ * Format: WL-YYYY-XXXXXX (where XXXXXX is sequential)
7
+ */
8
+ export function generateOrderNumber() {
9
+ const year = new Date().getFullYear();
10
+ const random = Math.floor(Math.random() * 1000000)
11
+ .toString()
12
+ .padStart(6, "0");
13
+ return `WL-${year}-${random}`;
14
+ }
15
+ /**
16
+ * Calculate order price based on weight and branch pricing
17
+ */
18
+ export function calculateOrderPrice(weight, pricingPerKg, deliveryFee, isDelivery) {
19
+ const basePrice = weight * pricingPerKg;
20
+ const fee = isDelivery ? deliveryFee : 0;
21
+ const totalPrice = basePrice + fee;
22
+ return {
23
+ basePrice: Math.round(basePrice * 100) / 100, // Round to 2 decimals
24
+ deliveryFee: fee,
25
+ totalPrice: Math.round(totalPrice * 100) / 100,
26
+ };
27
+ }
28
+ /**
29
+ * Calculate service price based on service type
30
+ * Service pricing:
31
+ * - wash_only: ₵25/load
32
+ * - wash_and_dry: ₵50/load
33
+ * - dry_only: ₵25/load
34
+ */
35
+ export function calculateServicePrice(serviceType, estimatedWeight, estimatedLoads, pricingPerKg, // Fallback pricing per kg
36
+ deliveryFee, isDelivery) {
37
+ // Service pricing per load
38
+ const servicePricing = {
39
+ wash_only: 25,
40
+ wash_and_dry: 50,
41
+ dry_only: 25,
42
+ };
43
+ // Calculate base price: service price per load × number of loads
44
+ // If loads not provided, estimate based on weight (assume ~3kg per load)
45
+ const loads = estimatedLoads || Math.ceil(estimatedWeight / 3);
46
+ const pricePerLoad = servicePricing[serviceType];
47
+ const basePrice = loads * pricePerLoad;
48
+ const fee = isDelivery ? deliveryFee : 0;
49
+ const totalPrice = basePrice + fee;
50
+ return {
51
+ basePrice: Math.round(basePrice * 100) / 100,
52
+ deliveryFee: fee,
53
+ totalPrice: Math.round(totalPrice * 100) / 100,
54
+ };
55
+ }
56
+ /**
57
+ * Format date to YYYY-MM-DD string
58
+ */
59
+ export function formatDate(date) {
60
+ const year = date.getFullYear();
61
+ const month = String(date.getMonth() + 1).padStart(2, "0");
62
+ const day = String(date.getDate()).padStart(2, "0");
63
+ return `${year}-${month}-${day}`;
64
+ }
65
+ /**
66
+ * Get current timestamp in milliseconds
67
+ */
68
+ export function getCurrentTimestamp() {
69
+ return Date.now();
70
+ }
71
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../convex/lib/utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC;SAC/C,QAAQ,EAAE;SACV,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpB,OAAO,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,YAAoB,EACpB,WAAmB,EACnB,UAAmB;IAMnB,MAAM,SAAS,GAAG,MAAM,GAAG,YAAY,CAAC;IACxC,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,SAAS,GAAG,GAAG,CAAC;IAEnC,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,sBAAsB;QACpE,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG;KAC/C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAsD,EACtD,eAAuB,EACvB,cAAsB,EACtB,YAAoB,EAAE,0BAA0B;AAChD,WAAmB,EACnB,UAAmB;IAMnB,2BAA2B;IAC3B,MAAM,cAAc,GAAG;QACrB,SAAS,EAAE,EAAE;QACb,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF,iEAAiE;IACjE,yEAAyE;IACzE,MAAM,KAAK,GAAG,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,CAAC;IAEvC,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,SAAS,GAAG,GAAG,CAAC;IAEnC,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG;QAC5C,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG;KAC/C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Loyalty Functions
3
+ *
4
+ * Handles loyalty points earning, redemption, and balance management.
5
+ * Rules: 1 point per completed order, 10 points = 1 free wash.
6
+ */
7
+ /**
8
+ * Get customer loyalty points balance
9
+ */
10
+ export declare const getBalance: import("convex/server").RegisteredQuery<"public", {}, Promise<{
11
+ points: number;
12
+ totalEarned: number;
13
+ totalRedeemed: number;
14
+ lastEarnedAt: number | undefined;
15
+ lastRedeemedAt: number | undefined;
16
+ }>>;
17
+ /**
18
+ * Get loyalty transaction history
19
+ */
20
+ /**
21
+ * Get loyalty transactions - Paginated
22
+ * Supports usePaginatedQuery for infinite scroll
23
+ */
24
+ export declare const getTransactions: import("convex/server").RegisteredQuery<"public", {
25
+ cursor?: string | undefined;
26
+ numItems?: number | undefined;
27
+ }, Promise<{
28
+ page: {
29
+ _id: import("convex/values").GenericId<"loyaltyTransactions">;
30
+ _creationTime: number;
31
+ createdBy?: import("convex/values").GenericId<"admins"> | undefined;
32
+ orderId?: import("convex/values").GenericId<"orders"> | undefined;
33
+ description?: string | undefined;
34
+ type: "earned" | "redeemed" | "expired" | "adjusted";
35
+ createdAt: number;
36
+ isDeleted: boolean;
37
+ customerId: import("convex/values").GenericId<"users">;
38
+ points: number;
39
+ balanceAfter: number;
40
+ }[];
41
+ isDone: boolean;
42
+ continueCursor: string;
43
+ }>>;
44
+ /**
45
+ * Earn loyalty points (internal - called when order is completed)
46
+ */
47
+ export declare const earnPoints: import("convex/server").RegisteredMutation<"internal", {
48
+ customerId: import("convex/values").GenericId<"users">;
49
+ orderId: import("convex/values").GenericId<"orders">;
50
+ points: number;
51
+ }, Promise<void>>;
52
+ /**
53
+ * Redeem loyalty points for free wash
54
+ */
55
+ export declare const redeemPoints: import("convex/server").RegisteredMutation<"public", {
56
+ orderId: import("convex/values").GenericId<"orders">;
57
+ pointsToRedeem: number;
58
+ }, Promise<{
59
+ pointsRedeemed: number;
60
+ newBalance: number;
61
+ discountAmount: number;
62
+ finalPrice: number;
63
+ }>>;
64
+ /**
65
+ * Adjust loyalty points (admin only)
66
+ */
67
+ export declare const adjustPoints: import("convex/server").RegisteredMutation<"public", {
68
+ customerId: import("convex/values").GenericId<"users">;
69
+ points: number;
70
+ description: string;
71
+ }, Promise<{
72
+ _id: import("convex/values").GenericId<"loyaltyPoints">;
73
+ _creationTime: number;
74
+ lastEarnedAt?: number | undefined;
75
+ lastRedeemedAt?: number | undefined;
76
+ isDeleted: boolean;
77
+ customerId: import("convex/values").GenericId<"users">;
78
+ points: number;
79
+ totalEarned: number;
80
+ totalRedeemed: number;
81
+ }>>;
82
+ //# sourceMappingURL=loyalty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loyalty.d.ts","sourceRoot":"","sources":["../../convex/loyalty.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;GA4BrB,CAAC;AAEH;;GAEG;AACH;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;GAyB1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU;;;;iBAiErB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;GAyFvB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;GAiEvB,CAAC"}