@iveri/contracts 0.42.0 → 0.44.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.
@@ -28,7 +28,11 @@ export interface ClinicAppointment {
28
28
  /** When the specialist, the room and any machine are free again, which includes the buffer. */
29
29
  blockedUntil: IsoDateTime;
30
30
  currency: string;
31
+ /** What the client pays, after any promotion. */
31
32
  totalMinor: number;
33
+ /** How much a promotion took off, as it stood when this was booked. */
34
+ discountMinor: number;
35
+ promotionName: Nullable<LocalizedText>;
32
36
  lines: ClinicAppointmentLine[];
33
37
  note: Nullable<string>;
34
38
  createdAt: IsoDateTime;
@@ -8,6 +8,12 @@ export interface ClinicClient {
8
8
  lastName: string;
9
9
  phone: string;
10
10
  email: Nullable<string>;
11
+ /**
12
+ * When the address in `email` was shown to belong to this client. Null means nothing is sent to
13
+ * it: anybody can register with an address that is not theirs, and a booking email carries a
14
+ * treatment name.
15
+ */
16
+ emailConfirmedAt: Nullable<IsoDateTime>;
11
17
  createdAt: IsoDateTime;
12
18
  updatedAt: IsoDateTime;
13
19
  }
@@ -16,6 +16,8 @@ export interface MyClinicAppointment {
16
16
  endsAt: IsoDateTime;
17
17
  currency: string;
18
18
  totalMinor: number;
19
+ discountMinor: number;
20
+ promotionName: Nullable<LocalizedText>;
19
21
  lines: ClinicAppointmentLine[];
20
22
  note: Nullable<string>;
21
23
  /** Whether the clinic's rules still let this client cancel it themselves. */
@@ -34,4 +36,10 @@ export interface SaveMyClinicClientRequest {
34
36
  lastName: string;
35
37
  phone: string;
36
38
  email?: Nullable<string>;
39
+ /** The language the client reads, which their emails are written in. */
40
+ localeCode?: string;
41
+ }
42
+ /** The token from a confirmation link. It is the only thing the public route accepts. */
43
+ export interface ConfirmClinicEmailRequest {
44
+ token: string;
37
45
  }
@@ -11,6 +11,8 @@ export interface ClinicProfile {
11
11
  tagline: Nullable<LocalizedText>;
12
12
  phone: Nullable<string>;
13
13
  email: Nullable<string>;
14
+ /** The clinic's public website, which the links in its emails point at. No path, no trailing slash. */
15
+ siteUrl: Nullable<string>;
14
16
  /** Nothing about the clinic is public until this is true. */
15
17
  isPublished: boolean;
16
18
  /** How long before a booking a client can still cancel it themselves. */
@@ -26,6 +28,7 @@ export interface SaveClinicProfileRequest {
26
28
  tagline?: Nullable<LocalizedText>;
27
29
  phone?: Nullable<string>;
28
30
  email?: Nullable<string>;
31
+ siteUrl?: Nullable<string>;
29
32
  isPublished: boolean;
30
33
  clientCancelCutoffHours: number;
31
34
  bookingHorizonDays: number;
@@ -0,0 +1,34 @@
1
+ import type { IsoDateTime } from '../../type/iso-date-time.type.js';
2
+ import type { Nullable } from '../../type/nil.type.js';
3
+ import type { UUID } from '../../type/uuid.type.js';
4
+ import type { LocalizedText } from './localized-text.type.js';
5
+ /**
6
+ * A percentage off the treatments it names, at the branches it names.
7
+ *
8
+ * `startsOn` and `endsOn` are calendar days (`YYYY-MM-DD`), both included, read in the branch's own
9
+ * time zone. What matters is the day of the visit, not the day it was booked.
10
+ */
11
+ export interface ClinicPromotion {
12
+ id: UUID;
13
+ name: LocalizedText;
14
+ description: Nullable<LocalizedText>;
15
+ discountPercent: number;
16
+ startsOn: string;
17
+ endsOn: string;
18
+ /** Whether the site may announce this across the top of every page. */
19
+ showInBanner: boolean;
20
+ treatmentIds: UUID[];
21
+ locationIds: UUID[];
22
+ createdAt: IsoDateTime;
23
+ updatedAt: IsoDateTime;
24
+ }
25
+ export interface SaveClinicPromotionRequest {
26
+ name: LocalizedText;
27
+ description?: Nullable<LocalizedText>;
28
+ discountPercent: number;
29
+ startsOn: string;
30
+ endsOn: string;
31
+ showInBanner: boolean;
32
+ treatmentIds: UUID[];
33
+ locationIds: UUID[];
34
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -34,6 +34,17 @@ export interface PublicTreatmentOption {
34
34
  name: LocalizedText;
35
35
  durationMinutes: number;
36
36
  priceMinor: number;
37
+ /** The price under the treatment's promotion, or null when there is none. */
38
+ promotionPriceMinor: Nullable<number>;
39
+ }
40
+ /** The best promotion running today for one treatment. */
41
+ export interface PublicTreatmentPromotion {
42
+ id: UUID;
43
+ name: LocalizedText;
44
+ discountPercent: number;
45
+ endsOn: string;
46
+ /** Where it applies. Booking at any other branch costs the full price. */
47
+ locationIds: UUID[];
37
48
  }
38
49
  export interface PublicTreatment {
39
50
  id: UUID;
@@ -44,6 +55,7 @@ export interface PublicTreatment {
44
55
  minDaysBetweenSessions: Nullable<number>;
45
56
  isBookableOnline: boolean;
46
57
  options: PublicTreatmentOption[];
58
+ promotion: Nullable<PublicTreatmentPromotion>;
47
59
  }
48
60
  export interface PublicSpecialist {
49
61
  id: UUID;
@@ -51,3 +63,15 @@ export interface PublicSpecialist {
51
63
  locationId: UUID;
52
64
  treatmentIds: UUID[];
53
65
  }
66
+ /** A promotion running today, biggest discount first. */
67
+ export interface PublicPromotion {
68
+ id: UUID;
69
+ name: LocalizedText;
70
+ description: Nullable<LocalizedText>;
71
+ discountPercent: number;
72
+ startsOn: string;
73
+ endsOn: string;
74
+ showInBanner: boolean;
75
+ treatmentIds: UUID[];
76
+ locationIds: UUID[];
77
+ }
@@ -1,9 +1,16 @@
1
1
  import type { IsoDateTime } from '../../type/iso-date-time.type.js';
2
+ import type { Nullable } from '../../type/nil.type.js';
2
3
  import type { UUID } from '../../type/uuid.type.js';
4
+ import type { LocalizedText } from './localized-text.type.js';
3
5
  /** A time one specialist can start this treatment, with a room and any machine free for all of it. */
4
6
  export interface ClinicSlot {
5
7
  staffMemberId: UUID;
6
8
  startsAt: IsoDateTime;
7
9
  /** When the treatment itself finishes, without the buffer after it. */
8
10
  endsAt: IsoDateTime;
11
+ /** What this visit would cost at this time, after any promotion. */
12
+ totalMinor: number;
13
+ /** How much a promotion takes off. Zero when none applies. */
14
+ discountMinor: number;
15
+ promotionName: Nullable<LocalizedText>;
9
16
  }
@@ -8,6 +8,7 @@ export * from './clinic-lead.type.js';
8
8
  export * from './clinic-location.type.js';
9
9
  export * from './clinic-my-appointment.type.js';
10
10
  export * from './clinic-profile.type.js';
11
+ export * from './clinic-promotion.type.js';
11
12
  export * from './clinic-public.type.js';
12
13
  export * from './clinic-resource-status.enum.js';
13
14
  export * from './clinic-room.type.js';
@@ -8,6 +8,7 @@ export * from './clinic-lead.type.js';
8
8
  export * from './clinic-location.type.js';
9
9
  export * from './clinic-my-appointment.type.js';
10
10
  export * from './clinic-profile.type.js';
11
+ export * from './clinic-promotion.type.js';
11
12
  export * from './clinic-public.type.js';
12
13
  export * from './clinic-resource-status.enum.js';
13
14
  export * from './clinic-room.type.js';
@@ -446,7 +446,11 @@ export declare enum UserPermission {
446
446
  /** Read callback requests and questions sent from a clinic's website or app. */
447
447
  CLINIC_LEAD_READ = "clinic:lead:read",
448
448
  /** Mark those requests as handled. */
449
- CLINIC_LEAD_MANAGE = "clinic:lead:manage"
449
+ CLINIC_LEAD_MANAGE = "clinic:lead:manage",
450
+ /** See what a clinic is promoting and publishing. */
451
+ CLINIC_MARKETING_READ = "clinic:marketing:read",
452
+ /** Change what a clinic is promoting and publishing, including its discounts. */
453
+ CLINIC_MARKETING_MANAGE = "clinic:marketing:manage"
450
454
  }
451
455
  /**
452
456
  * Every member, for seeding the owner role and validating custom-role input.
@@ -509,6 +509,10 @@ export var UserPermission;
509
509
  UserPermission["CLINIC_LEAD_READ"] = "clinic:lead:read";
510
510
  /** Mark those requests as handled. */
511
511
  UserPermission["CLINIC_LEAD_MANAGE"] = "clinic:lead:manage";
512
+ /** See what a clinic is promoting and publishing. */
513
+ UserPermission["CLINIC_MARKETING_READ"] = "clinic:marketing:read";
514
+ /** Change what a clinic is promoting and publishing, including its discounts. */
515
+ UserPermission["CLINIC_MARKETING_MANAGE"] = "clinic:marketing:manage";
512
516
  })(UserPermission || (UserPermission = {}));
513
517
  /**
514
518
  * Every member, for seeding the owner role and validating custom-role input.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iveri/contracts",
3
- "version": "0.42.0",
3
+ "version": "0.44.0",
4
4
  "description": "Wire contracts shared by every Iveri backend and frontend. Zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "repository": {