@voxendar/shared 0.1.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.
Files changed (49) hide show
  1. package/dist/constants.d.ts +31 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +46 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/i18n/templates.d.ts +25 -0
  6. package/dist/i18n/templates.d.ts.map +1 -0
  7. package/dist/i18n/templates.js +38 -0
  8. package/dist/i18n/templates.js.map +1 -0
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +28 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/reminders/math.d.ts +17 -0
  14. package/dist/reminders/math.d.ts.map +1 -0
  15. package/dist/reminders/math.js +33 -0
  16. package/dist/reminders/math.js.map +1 -0
  17. package/dist/schemas/capture.d.ts +92 -0
  18. package/dist/schemas/capture.d.ts.map +1 -0
  19. package/dist/schemas/capture.js +24 -0
  20. package/dist/schemas/capture.js.map +1 -0
  21. package/dist/schemas/circle.d.ts +23 -0
  22. package/dist/schemas/circle.d.ts.map +1 -0
  23. package/dist/schemas/circle.js +17 -0
  24. package/dist/schemas/circle.js.map +1 -0
  25. package/dist/schemas/enums.d.ts +11 -0
  26. package/dist/schemas/enums.d.ts.map +1 -0
  27. package/dist/schemas/enums.js +14 -0
  28. package/dist/schemas/enums.js.map +1 -0
  29. package/dist/schemas/error.d.ts +14 -0
  30. package/dist/schemas/error.d.ts.map +1 -0
  31. package/dist/schemas/error.js +37 -0
  32. package/dist/schemas/error.js.map +1 -0
  33. package/dist/schemas/event.d.ts +47 -0
  34. package/dist/schemas/event.d.ts.map +1 -0
  35. package/dist/schemas/event.js +27 -0
  36. package/dist/schemas/event.js.map +1 -0
  37. package/dist/schemas/member.d.ts +80 -0
  38. package/dist/schemas/member.d.ts.map +1 -0
  39. package/dist/schemas/member.js +41 -0
  40. package/dist/schemas/member.js.map +1 -0
  41. package/dist/schemas/primitives.d.ts +17 -0
  42. package/dist/schemas/primitives.d.ts.map +1 -0
  43. package/dist/schemas/primitives.js +20 -0
  44. package/dist/schemas/primitives.js.map +1 -0
  45. package/dist/schemas/reminder.d.ts +33 -0
  46. package/dist/schemas/reminder.d.ts.map +1 -0
  47. package/dist/schemas/reminder.js +21 -0
  48. package/dist/schemas/reminder.js.map +1 -0
  49. package/package.json +24 -0
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared domain constants.
3
+ * NOTE: naming and values are placeholder scope. The real launch-language set,
4
+ * channel policy, and provider choices are confirmed by Rob in Phase 0
5
+ * (Implementation_Plan.md Phase 0).
6
+ */
7
+ /** Candidate launch languages (2–3 to start, per context.md §10). */
8
+ export declare const SUPPORTED_LANGUAGES: readonly ["en-US", "zh-CN", "es-MX"];
9
+ /** Google Calendar color ids "1"–"11" (color-to-member assignment decided in Phase 0). */
10
+ export declare const GOOGLE_CALENDAR_COLOR_IDS: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"];
11
+ /** Default per-event reminder offsets in minutes (1 day, 2 hours). */
12
+ export declare const DEFAULT_REMINDER_OFFSETS_MINUTES: readonly [1440, 120];
13
+ /** Scheduled dispatch interval for `dispatchReminders` (minutes). */
14
+ export declare const SCHEDULER_INTERVAL_MINUTES_DEFAULT = 15;
15
+ /** Safety margin added to the reminder query horizon (minutes). */
16
+ export declare const SCHEDULER_HORIZON_MARGIN_MINUTES_DEFAULT = 360;
17
+ /** Firebase collection names. */
18
+ export declare const FIRESTORE_COLLECTIONS: {
19
+ readonly userProfiles: "userProfiles";
20
+ readonly userGoogleTokens: "userGoogleTokens";
21
+ readonly families: "families";
22
+ readonly members: "members";
23
+ readonly captures: "captures";
24
+ readonly sentReminders: "sentReminders";
25
+ };
26
+ /** Firebase Storage path prefixes. */
27
+ export declare const STORAGE_PATHS: {
28
+ readonly rawAudio: "audio";
29
+ readonly ttsClips: "tts";
30
+ };
31
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,sCAAuC,CAAC;AAExE,0FAA0F;AAC1F,eAAO,MAAM,yBAAyB,oEAY5B,CAAC;AAEX,sEAAsE;AACtE,eAAO,MAAM,gCAAgC,sBAAuB,CAAC;AAErE,qEAAqE;AACrE,eAAO,MAAM,kCAAkC,KAAK,CAAC;AAErD,mEAAmE;AACnE,eAAO,MAAM,wCAAwC,MAAM,CAAC;AAE5D,iCAAiC;AACjC,eAAO,MAAM,qBAAqB;;;;;;;CAOxB,CAAC;AAEX,sCAAsC;AACtC,eAAO,MAAM,aAAa;;;CAGhB,CAAC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Shared domain constants.
4
+ * NOTE: naming and values are placeholder scope. The real launch-language set,
5
+ * channel policy, and provider choices are confirmed by Rob in Phase 0
6
+ * (Implementation_Plan.md Phase 0).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.STORAGE_PATHS = exports.FIRESTORE_COLLECTIONS = exports.SCHEDULER_HORIZON_MARGIN_MINUTES_DEFAULT = exports.SCHEDULER_INTERVAL_MINUTES_DEFAULT = exports.DEFAULT_REMINDER_OFFSETS_MINUTES = exports.GOOGLE_CALENDAR_COLOR_IDS = exports.SUPPORTED_LANGUAGES = void 0;
10
+ /** Candidate launch languages (2–3 to start, per context.md §10). */
11
+ exports.SUPPORTED_LANGUAGES = ["en-US", "zh-CN", "es-MX"];
12
+ /** Google Calendar color ids "1"–"11" (color-to-member assignment decided in Phase 0). */
13
+ exports.GOOGLE_CALENDAR_COLOR_IDS = [
14
+ "1",
15
+ "2",
16
+ "3",
17
+ "4",
18
+ "5",
19
+ "6",
20
+ "7",
21
+ "8",
22
+ "9",
23
+ "10",
24
+ "11",
25
+ ];
26
+ /** Default per-event reminder offsets in minutes (1 day, 2 hours). */
27
+ exports.DEFAULT_REMINDER_OFFSETS_MINUTES = [1440, 120];
28
+ /** Scheduled dispatch interval for `dispatchReminders` (minutes). */
29
+ exports.SCHEDULER_INTERVAL_MINUTES_DEFAULT = 15;
30
+ /** Safety margin added to the reminder query horizon (minutes). */
31
+ exports.SCHEDULER_HORIZON_MARGIN_MINUTES_DEFAULT = 360;
32
+ /** Firebase collection names. */
33
+ exports.FIRESTORE_COLLECTIONS = {
34
+ userProfiles: "userProfiles",
35
+ userGoogleTokens: "userGoogleTokens",
36
+ families: "families",
37
+ members: "members",
38
+ captures: "captures",
39
+ sentReminders: "sentReminders",
40
+ };
41
+ /** Firebase Storage path prefixes. */
42
+ exports.STORAGE_PATHS = {
43
+ rawAudio: "audio", // audio/{uid}/... — deleted after transcription
44
+ ttsClips: "tts", // tts/{...} — cacheable spoken confirmations
45
+ };
46
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qEAAqE;AACxD,QAAA,mBAAmB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAExE,0FAA0F;AAC7E,QAAA,yBAAyB,GAAG;IACvC,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;CACI,CAAC;AAEX,sEAAsE;AACzD,QAAA,gCAAgC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAU,CAAC;AAErE,qEAAqE;AACxD,QAAA,kCAAkC,GAAG,EAAE,CAAC;AAErD,mEAAmE;AACtD,QAAA,wCAAwC,GAAG,GAAG,CAAC;AAE5D,iCAAiC;AACpB,QAAA,qBAAqB,GAAG;IACnC,YAAY,EAAE,cAAc;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,eAAe;CACtB,CAAC;AAEX,sCAAsC;AACzB,QAAA,aAAa,GAAG;IAC3B,QAAQ,EAAE,OAAO,EAAE,gDAAgD;IACnE,QAAQ,EAAE,KAAK,EAAE,6CAA6C;CACtD,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Reminder message templates (README §5a).
3
+ * A template library — not free-form LLM copy — keeps SMS segment billing
4
+ * predictable and copy consistent across channels and languages.
5
+ */
6
+ export interface ReminderMessageParams {
7
+ /** Event title. */
8
+ title: string;
9
+ /** Human-friendly time phrase already resolved in the recipient's timezone. */
10
+ when: string;
11
+ /** Optional location included in the message. */
12
+ location?: string | null;
13
+ }
14
+ declare const TEMPLATES: {
15
+ readonly "en-US": (p: ReminderMessageParams) => string;
16
+ readonly "zh-CN": (p: ReminderMessageParams) => string;
17
+ readonly "es-MX": (p: ReminderMessageParams) => string;
18
+ };
19
+ export type TemplateKey = keyof typeof TEMPLATES;
20
+ /** Closest template for a BCP-47 tag: exact → base language ("zh" → "zh-CN") → "en-US". */
21
+ export declare function resolveTemplateKey(language: string): TemplateKey;
22
+ /** Build the reminder message text for a member's language. */
23
+ export declare function buildReminderMessage(language: string, params: ReminderMessageParams): string;
24
+ export {};
25
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/i18n/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,qBAAqB;IACpC,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,QAAA,MAAM,SAAS;0BACA,qBAAqB,KAAG,MAAM;0BAI9B,qBAAqB,KAAG,MAAM;0BAI9B,qBAAqB,KAAG,MAAM;CAI4B,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,SAAS,CAAC;AAEjD,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAUhE;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAG5F"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Reminder message templates (README §5a).
4
+ * A template library — not free-form LLM copy — keeps SMS segment billing
5
+ * predictable and copy consistent across channels and languages.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.resolveTemplateKey = resolveTemplateKey;
9
+ exports.buildReminderMessage = buildReminderMessage;
10
+ const TEMPLATES = {
11
+ "en-US": (p) => p.location
12
+ ? `⏰ Reminder: ${p.title} — ${p.when} (📍 ${p.location})`
13
+ : `⏰ Reminder: ${p.title} — ${p.when}`,
14
+ "zh-CN": (p) => p.location
15
+ ? `⏰ 提醒:${p.title},${p.when}(📍 ${p.location})`
16
+ : `⏰ 提醒:${p.title},${p.when}`,
17
+ "es-MX": (p) => p.location
18
+ ? `⏰ Recordatorio: ${p.title} — ${p.when} (📍 ${p.location})`
19
+ : `⏰ Recordatorio: ${p.title} — ${p.when}`,
20
+ };
21
+ /** Closest template for a BCP-47 tag: exact → base language ("zh" → "zh-CN") → "en-US". */
22
+ function resolveTemplateKey(language) {
23
+ if (language in TEMPLATES)
24
+ return language;
25
+ const base = language.split("-")[0] ?? "";
26
+ if (base.length >= 2) {
27
+ const baseKey = Object.keys(TEMPLATES).find((key) => key.startsWith(`${base}-`));
28
+ if (baseKey)
29
+ return baseKey;
30
+ }
31
+ return "en-US";
32
+ }
33
+ /** Build the reminder message text for a member's language. */
34
+ function buildReminderMessage(language, params) {
35
+ const templateKey = resolveTemplateKey(language);
36
+ return TEMPLATES[templateKey](params);
37
+ }
38
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/i18n/templates.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA6BH,gDAUC;AAGD,oDAGC;AAlCD,MAAM,SAAS,GAAG;IAChB,OAAO,EAAE,CAAC,CAAwB,EAAU,EAAE,CAC5C,CAAC,CAAC,QAAQ;QACR,CAAC,CAAC,eAAe,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,QAAQ,GAAG;QACzD,CAAC,CAAC,eAAe,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,CAAC,CAAwB,EAAU,EAAE,CAC5C,CAAC,CAAC,QAAQ;QACR,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,GAAG;QAC/C,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE;IACjC,OAAO,EAAE,CAAC,CAAwB,EAAU,EAAE,CAC5C,CAAC,CAAC,QAAQ;QACR,CAAC,CAAC,mBAAmB,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,QAAQ,GAAG;QAC7D,CAAC,CAAC,mBAAmB,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,EAAE;CACyB,CAAC;AAI1E,2FAA2F;AAC3F,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,IAAI,QAAQ,IAAI,SAAS;QAAE,OAAO,QAAuB,CAAC;IAC1D,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,OAAO,GAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAmB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACrE,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAC3B,CAAC;QACF,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+DAA+D;AAC/D,SAAgB,oBAAoB,CAAC,QAAgB,EAAE,MAA6B;IAClF,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export * from "./constants";
2
+ export * from "./schemas/enums";
3
+ export * from "./schemas/primitives";
4
+ export * from "./schemas/error";
5
+ export * from "./schemas/event";
6
+ export * from "./schemas/circle";
7
+ export * from "./schemas/member";
8
+ export * from "./schemas/capture";
9
+ export * from "./schemas/reminder";
10
+ export * from "./reminders/math";
11
+ export * from "./i18n/templates";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./constants"), exports);
18
+ __exportStar(require("./schemas/enums"), exports);
19
+ __exportStar(require("./schemas/primitives"), exports);
20
+ __exportStar(require("./schemas/error"), exports);
21
+ __exportStar(require("./schemas/event"), exports);
22
+ __exportStar(require("./schemas/circle"), exports);
23
+ __exportStar(require("./schemas/member"), exports);
24
+ __exportStar(require("./schemas/capture"), exports);
25
+ __exportStar(require("./schemas/reminder"), exports);
26
+ __exportStar(require("./reminders/math"), exports);
27
+ __exportStar(require("./i18n/templates"), exports);
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,kDAAgC;AAChC,uDAAqC;AACrC,kDAAgC;AAChC,kDAAgC;AAChC,mDAAiC;AACjC,mDAAiC;AACjC,oDAAkC;AAClC,qDAAmC;AACnC,mDAAiC;AACjC,mDAAiC"}
@@ -0,0 +1,17 @@
1
+ import { NOTIFY_CHANNELS } from "../schemas/enums";
2
+ /**
3
+ * Reminder query horizon (README §5a): the largest offset present + the job
4
+ * interval + a safety margin, so a 1-day-before reminder at the window's edge
5
+ * is never missed.
6
+ */
7
+ export declare function computeReminderQueryHorizonMinutes(offsets?: readonly number[], opts?: {
8
+ intervalMinutes?: number;
9
+ marginMinutes?: number;
10
+ }): number;
11
+ /** A reminder for `eventStartMs` with `offsetMinutes` is due once now >= start - offset. */
12
+ export declare function isReminderDue(eventStartMs: number, offsetMinutes: number, nowMs: number): boolean;
13
+ /** Deterministic sentReminders doc id (create-if-absent for idempotency). */
14
+ export declare function reminderIdKey(eventId: string, offsetMinutes: number, channel: (typeof NOTIFY_CHANNELS)[number]): string;
15
+ /** All-day events: the 1-day reminder fires at previous local midnight (UTC math handled by caller). */
16
+ export declare function allDayReminderInstant(dayStartLocalMs: number, offsetMinutes: number): number;
17
+ //# sourceMappingURL=math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/reminders/math.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,SAAS,MAAM,EAAqC,EAC7D,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,MAAM,CAOR;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjG;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,GACxC,MAAM,CAER;AAED,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAE5F"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeReminderQueryHorizonMinutes = computeReminderQueryHorizonMinutes;
4
+ exports.isReminderDue = isReminderDue;
5
+ exports.reminderIdKey = reminderIdKey;
6
+ exports.allDayReminderInstant = allDayReminderInstant;
7
+ const constants_1 = require("../constants");
8
+ /**
9
+ * Reminder query horizon (README §5a): the largest offset present + the job
10
+ * interval + a safety margin, so a 1-day-before reminder at the window's edge
11
+ * is never missed.
12
+ */
13
+ function computeReminderQueryHorizonMinutes(offsets = constants_1.DEFAULT_REMINDER_OFFSETS_MINUTES, opts = {}) {
14
+ const { intervalMinutes = 15, marginMinutes = 360 } = opts;
15
+ if (offsets.length === 0) {
16
+ throw new Error("at least one reminder offset is required");
17
+ }
18
+ const maxOffset = Math.max(...offsets);
19
+ return maxOffset + intervalMinutes + marginMinutes;
20
+ }
21
+ /** A reminder for `eventStartMs` with `offsetMinutes` is due once now >= start - offset. */
22
+ function isReminderDue(eventStartMs, offsetMinutes, nowMs) {
23
+ return nowMs >= eventStartMs - offsetMinutes * 60_000;
24
+ }
25
+ /** Deterministic sentReminders doc id (create-if-absent for idempotency). */
26
+ function reminderIdKey(eventId, offsetMinutes, channel) {
27
+ return `${eventId}_${offsetMinutes}_${channel}`;
28
+ }
29
+ /** All-day events: the 1-day reminder fires at previous local midnight (UTC math handled by caller). */
30
+ function allDayReminderInstant(dayStartLocalMs, offsetMinutes) {
31
+ return dayStartLocalMs - offsetMinutes * 60_000;
32
+ }
33
+ //# sourceMappingURL=math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/reminders/math.ts"],"names":[],"mappings":";;AAQA,gFAUC;AAGD,sCAEC;AAGD,sCAMC;AAGD,sDAEC;AArCD,4CAAgE;AAGhE;;;;GAIG;AACH,SAAgB,kCAAkC,CAChD,UAA6B,4CAAgC,EAC7D,OAA6D,EAAE;IAE/D,MAAM,EAAE,eAAe,GAAG,EAAE,EAAE,aAAa,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IACvC,OAAO,SAAS,GAAG,eAAe,GAAG,aAAa,CAAC;AACrD,CAAC;AAED,4FAA4F;AAC5F,SAAgB,aAAa,CAAC,YAAoB,EAAE,aAAqB,EAAE,KAAa;IACtF,OAAO,KAAK,IAAI,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AACxD,CAAC;AAED,6EAA6E;AAC7E,SAAgB,aAAa,CAC3B,OAAe,EACf,aAAqB,EACrB,OAAyC;IAEzC,OAAO,GAAG,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;AAClD,CAAC;AAED,wGAAwG;AACxG,SAAgB,qBAAqB,CAAC,eAAuB,EAAE,aAAqB;IAClF,OAAO,eAAe,GAAG,aAAa,GAAG,MAAM,CAAC;AAClD,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * `families/{familyId}/captures/{captureId}` — audit/debug log, not user-facing
4
+ * (README §3). `editedFields` is the accuracy telemetry behind the
5
+ * confirmation-fatigue risk (README §8).
6
+ */
7
+ export declare const CaptureSchema: z.ZodObject<{
8
+ memberId: z.ZodString;
9
+ source: z.ZodEnum<["voice", "email", "chat"]>;
10
+ rawText: z.ZodString;
11
+ extractedEvent: z.ZodNullable<z.ZodObject<{
12
+ title: z.ZodString;
13
+ start: z.ZodString;
14
+ end: z.ZodNullable<z.ZodOptional<z.ZodString>>;
15
+ timeZone: z.ZodString;
16
+ allDay: z.ZodDefault<z.ZodBoolean>;
17
+ location: z.ZodNullable<z.ZodOptional<z.ZodString>>;
18
+ notes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
19
+ confidence: z.ZodEnum<["high", "medium", "low"]>;
20
+ ambiguities: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
21
+ spokenConfirmation: z.ZodString;
22
+ }, "strip", z.ZodTypeAny, {
23
+ title: string;
24
+ start: string;
25
+ timeZone: string;
26
+ allDay: boolean;
27
+ confidence: "high" | "medium" | "low";
28
+ ambiguities: string[];
29
+ spokenConfirmation: string;
30
+ end?: string | null | undefined;
31
+ location?: string | null | undefined;
32
+ notes?: string | null | undefined;
33
+ }, {
34
+ title: string;
35
+ start: string;
36
+ timeZone: string;
37
+ confidence: "high" | "medium" | "low";
38
+ spokenConfirmation: string;
39
+ end?: string | null | undefined;
40
+ allDay?: boolean | undefined;
41
+ location?: string | null | undefined;
42
+ notes?: string | null | undefined;
43
+ ambiguities?: string[] | undefined;
44
+ }>>;
45
+ status: z.ZodEnum<["pending_confirmation", "confirmed", "discarded"]>;
46
+ /** Fields the user corrected on the confirmation card. */
47
+ editedFields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
48
+ googleEventId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
+ createdAt: z.ZodAny;
50
+ }, "strip", z.ZodTypeAny, {
51
+ status: "pending_confirmation" | "confirmed" | "discarded";
52
+ memberId: string;
53
+ source: "voice" | "email" | "chat";
54
+ rawText: string;
55
+ extractedEvent: {
56
+ title: string;
57
+ start: string;
58
+ timeZone: string;
59
+ allDay: boolean;
60
+ confidence: "high" | "medium" | "low";
61
+ ambiguities: string[];
62
+ spokenConfirmation: string;
63
+ end?: string | null | undefined;
64
+ location?: string | null | undefined;
65
+ notes?: string | null | undefined;
66
+ } | null;
67
+ editedFields: string[];
68
+ createdAt?: any;
69
+ googleEventId?: string | null | undefined;
70
+ }, {
71
+ status: "pending_confirmation" | "confirmed" | "discarded";
72
+ memberId: string;
73
+ source: "voice" | "email" | "chat";
74
+ rawText: string;
75
+ extractedEvent: {
76
+ title: string;
77
+ start: string;
78
+ timeZone: string;
79
+ confidence: "high" | "medium" | "low";
80
+ spokenConfirmation: string;
81
+ end?: string | null | undefined;
82
+ allDay?: boolean | undefined;
83
+ location?: string | null | undefined;
84
+ notes?: string | null | undefined;
85
+ ambiguities?: string[] | undefined;
86
+ } | null;
87
+ createdAt?: any;
88
+ editedFields?: string[] | undefined;
89
+ googleEventId?: string | null | undefined;
90
+ }>;
91
+ export type Capture = z.infer<typeof CaptureSchema>;
92
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/schemas/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMxB,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI1D,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CaptureSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const enums_1 = require("./enums");
6
+ const primitives_1 = require("./primitives");
7
+ const event_1 = require("./event");
8
+ /**
9
+ * `families/{familyId}/captures/{captureId}` — audit/debug log, not user-facing
10
+ * (README §3). `editedFields` is the accuracy telemetry behind the
11
+ * confirmation-fatigue risk (README §8).
12
+ */
13
+ exports.CaptureSchema = zod_1.z.object({
14
+ memberId: zod_1.z.string().min(1),
15
+ source: zod_1.z.enum(enums_1.CAPTURE_SOURCES),
16
+ rawText: zod_1.z.string(),
17
+ extractedEvent: event_1.EventDraftSchema.nullable(),
18
+ status: zod_1.z.enum(enums_1.CAPTURE_STATUSES),
19
+ /** Fields the user corrected on the confirmation card. */
20
+ editedFields: zod_1.z.array(zod_1.z.string()).default([]),
21
+ googleEventId: zod_1.z.string().nullish(),
22
+ createdAt: primitives_1.firestoreTimestamp,
23
+ });
24
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/schemas/capture.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,mCAA4D;AAC5D,6CAAkD;AAClD,mCAA2C;AAE3C;;;;GAIG;AACU,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,uBAAe,CAAC;IAC/B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,cAAc,EAAE,wBAAgB,CAAC,QAAQ,EAAE;IAC3C,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,wBAAgB,CAAC;IAChC,0DAA0D;IAC1D,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IACnC,SAAS,EAAE,+BAAkB;CAC9B,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * `families/{familyId}` — a "circle". Size 1 = solo, size N = group; the same
4
+ * entity either way (README §3, context.md §4).
5
+ */
6
+ export declare const CircleSchema: z.ZodObject<{
7
+ name: z.ZodString;
8
+ googleCalendarId: z.ZodString;
9
+ calendarMode: z.ZodEnum<["primary", "provisioned"]>;
10
+ createdAt: z.ZodAny;
11
+ }, "strip", z.ZodTypeAny, {
12
+ name: string;
13
+ googleCalendarId: string;
14
+ calendarMode: "primary" | "provisioned";
15
+ createdAt?: any;
16
+ }, {
17
+ name: string;
18
+ googleCalendarId: string;
19
+ calendarMode: "primary" | "provisioned";
20
+ createdAt?: any;
21
+ }>;
22
+ export type Circle = z.infer<typeof CircleSchema>;
23
+ //# sourceMappingURL=circle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circle.d.ts","sourceRoot":"","sources":["../../src/schemas/circle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;EAKvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CircleSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const enums_1 = require("./enums");
6
+ const primitives_1 = require("./primitives");
7
+ /**
8
+ * `families/{familyId}` — a "circle". Size 1 = solo, size N = group; the same
9
+ * entity either way (README §3, context.md §4).
10
+ */
11
+ exports.CircleSchema = zod_1.z.object({
12
+ name: zod_1.z.string().min(1).max(100),
13
+ googleCalendarId: zod_1.z.string().min(1),
14
+ calendarMode: zod_1.z.enum(enums_1.CIRCLE_MODES),
15
+ createdAt: primitives_1.firestoreTimestamp,
16
+ });
17
+ //# sourceMappingURL=circle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circle.js","sourceRoot":"","sources":["../../src/schemas/circle.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,mCAAuC;AACvC,6CAAkD;AAElD;;;GAGG;AACU,QAAA,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAChC,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,YAAY,EAAE,OAAC,CAAC,IAAI,CAAC,oBAAY,CAAC;IAClC,SAAS,EAAE,+BAAkB;CAC9B,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Shared domain enums — single source of truth for both backend and app. */
2
+ export declare const AUTH_TYPES: readonly ["google", "profile"];
3
+ export declare const CAPTURE_SOURCES: readonly ["voice", "email", "chat"];
4
+ export declare const CAPTURE_STATUSES: readonly ["pending_confirmation", "confirmed", "discarded"];
5
+ export declare const CHANNEL_STATUSES: readonly ["opted_in", "pending", "failed"];
6
+ export declare const CIRCLE_MODES: readonly ["primary", "provisioned"];
7
+ export declare const CONFIDENCE_LEVELS: readonly ["high", "medium", "low"];
8
+ export declare const NOTIFY_CHANNELS: readonly ["sms", "whatsapp", "telegram"];
9
+ export declare const REMINDER_STATUSES: readonly ["sent", "failed", "skipped"];
10
+ export declare const VOICE_STYLE_PRESETS: readonly ["professional", "warm_casual", "friendly_brief"];
11
+ //# sourceMappingURL=enums.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/schemas/enums.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,eAAO,MAAM,UAAU,gCAAiC,CAAC;AACzD,eAAO,MAAM,eAAe,qCAAsC,CAAC;AACnE,eAAO,MAAM,gBAAgB,6DAA8D,CAAC;AAC5F,eAAO,MAAM,gBAAgB,4CAA6C,CAAC;AAC3E,eAAO,MAAM,YAAY,qCAAsC,CAAC;AAChE,eAAO,MAAM,iBAAiB,oCAAqC,CAAC;AACpE,eAAO,MAAM,eAAe,0CAA2C,CAAC;AACxE,eAAO,MAAM,iBAAiB,wCAAyC,CAAC;AACxE,eAAO,MAAM,mBAAmB,4DAA6D,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /** Shared domain enums — single source of truth for both backend and app. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.VOICE_STYLE_PRESETS = exports.REMINDER_STATUSES = exports.NOTIFY_CHANNELS = exports.CONFIDENCE_LEVELS = exports.CIRCLE_MODES = exports.CHANNEL_STATUSES = exports.CAPTURE_STATUSES = exports.CAPTURE_SOURCES = exports.AUTH_TYPES = void 0;
5
+ exports.AUTH_TYPES = ["google", "profile"];
6
+ exports.CAPTURE_SOURCES = ["voice", "email", "chat"];
7
+ exports.CAPTURE_STATUSES = ["pending_confirmation", "confirmed", "discarded"];
8
+ exports.CHANNEL_STATUSES = ["opted_in", "pending", "failed"];
9
+ exports.CIRCLE_MODES = ["primary", "provisioned"];
10
+ exports.CONFIDENCE_LEVELS = ["high", "medium", "low"];
11
+ exports.NOTIFY_CHANNELS = ["sms", "whatsapp", "telegram"];
12
+ exports.REMINDER_STATUSES = ["sent", "failed", "skipped"];
13
+ exports.VOICE_STYLE_PRESETS = ["professional", "warm_casual", "friendly_brief"];
14
+ //# sourceMappingURL=enums.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.js","sourceRoot":"","sources":["../../src/schemas/enums.ts"],"names":[],"mappings":";AAAA,6EAA6E;;;AAEhE,QAAA,UAAU,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAU,CAAC;AAC5C,QAAA,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AACtD,QAAA,gBAAgB,GAAG,CAAC,sBAAsB,EAAE,WAAW,EAAE,WAAW,CAAU,CAAC;AAC/E,QAAA,gBAAgB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAC9D,QAAA,YAAY,GAAG,CAAC,SAAS,EAAE,aAAa,CAAU,CAAC;AACnD,QAAA,iBAAiB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAC;AACvD,QAAA,eAAe,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,CAAU,CAAC;AAC3D,QAAA,iBAAiB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAC3D,QAAA,mBAAmB,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,gBAAgB,CAAU,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Application error codes shared across backend functions and the app.
3
+ * This is the M1.10 graceful-failure contract (Implementation_Plan.md M1.10).
4
+ */
5
+ export declare const ERROR_CODES: readonly ["ASR_FAILED", "EXTRACTION_FAILED", "TTS_FAILED", "CALENDAR_QUOTA", "NEEDS_OPT_IN", "AUTH_REQUIRED", "VALIDATION_FAILED", "NOT_FOUND", "CHANNEL_FAILED", "RATE_LIMITED", "UNKNOWN"];
6
+ export type ErrorCode = (typeof ERROR_CODES)[number];
7
+ /** Typed application error with a stable machine-readable code for the UI. */
8
+ export declare class AppError extends Error {
9
+ readonly code: ErrorCode;
10
+ readonly details?: unknown;
11
+ constructor(code: ErrorCode, message: string, details?: unknown);
12
+ }
13
+ export declare function isAppError(error: unknown): error is AppError;
14
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/schemas/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,8LAYd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,8EAA8E;AAC9E,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAEf,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAMhE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppError = exports.ERROR_CODES = void 0;
4
+ exports.isAppError = isAppError;
5
+ /**
6
+ * Application error codes shared across backend functions and the app.
7
+ * This is the M1.10 graceful-failure contract (Implementation_Plan.md M1.10).
8
+ */
9
+ exports.ERROR_CODES = [
10
+ "ASR_FAILED",
11
+ "EXTRACTION_FAILED",
12
+ "TTS_FAILED",
13
+ "CALENDAR_QUOTA",
14
+ "NEEDS_OPT_IN",
15
+ "AUTH_REQUIRED",
16
+ "VALIDATION_FAILED",
17
+ "NOT_FOUND",
18
+ "CHANNEL_FAILED",
19
+ "RATE_LIMITED",
20
+ "UNKNOWN",
21
+ ];
22
+ /** Typed application error with a stable machine-readable code for the UI. */
23
+ class AppError extends Error {
24
+ code;
25
+ details;
26
+ constructor(code, message, details) {
27
+ super(message);
28
+ this.name = "AppError";
29
+ this.code = code;
30
+ this.details = details;
31
+ }
32
+ }
33
+ exports.AppError = AppError;
34
+ function isAppError(error) {
35
+ return error instanceof AppError;
36
+ }
37
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/schemas/error.ts"],"names":[],"mappings":";;;AAiCA,gCAEC;AAnCD;;;GAGG;AACU,QAAA,WAAW,GAAG;IACzB,YAAY;IACZ,mBAAmB;IACnB,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,WAAW;IACX,gBAAgB;IAChB,cAAc;IACd,SAAS;CACD,CAAC;AAIX,8EAA8E;AAC9E,MAAa,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAY;IAChB,OAAO,CAAW;IAE3B,YAAY,IAAe,EAAE,OAAe,EAAE,OAAiB;QAC7D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAVD,4BAUC;AAED,SAAgB,UAAU,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,QAAQ,CAAC;AACnC,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { CONFIDENCE_LEVELS } from "./enums";
3
+ /**
4
+ * EventDraft — the extraction-pipeline output (README §4) and the payload a
5
+ * confirmation card edits before confirmEvent writes it to Google Calendar.
6
+ */
7
+ export declare const EventDraftSchema: z.ZodObject<{
8
+ title: z.ZodString;
9
+ start: z.ZodString;
10
+ end: z.ZodNullable<z.ZodOptional<z.ZodString>>;
11
+ timeZone: z.ZodString;
12
+ allDay: z.ZodDefault<z.ZodBoolean>;
13
+ location: z.ZodNullable<z.ZodOptional<z.ZodString>>;
14
+ notes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
15
+ confidence: z.ZodEnum<["high", "medium", "low"]>;
16
+ ambiguities: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
17
+ /**
18
+ * TTS string read back to the user — generated in the same LLM call so there
19
+ * is no second LLM call per capture (README §4).
20
+ */
21
+ spokenConfirmation: z.ZodString;
22
+ }, "strip", z.ZodTypeAny, {
23
+ title: string;
24
+ start: string;
25
+ timeZone: string;
26
+ allDay: boolean;
27
+ confidence: "high" | "medium" | "low";
28
+ ambiguities: string[];
29
+ spokenConfirmation: string;
30
+ end?: string | null | undefined;
31
+ location?: string | null | undefined;
32
+ notes?: string | null | undefined;
33
+ }, {
34
+ title: string;
35
+ start: string;
36
+ timeZone: string;
37
+ confidence: "high" | "medium" | "low";
38
+ spokenConfirmation: string;
39
+ end?: string | null | undefined;
40
+ allDay?: boolean | undefined;
41
+ location?: string | null | undefined;
42
+ notes?: string | null | undefined;
43
+ ambiguities?: string[] | undefined;
44
+ }>;
45
+ export type EventDraft = z.infer<typeof EventDraftSchema>;
46
+ export type ConfidenceLevel = (typeof CONFIDENCE_LEVELS)[number];
47
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/schemas/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAG5C;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;IAU3B;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventDraftSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const enums_1 = require("./enums");
6
+ const primitives_1 = require("./primitives");
7
+ /**
8
+ * EventDraft — the extraction-pipeline output (README §4) and the payload a
9
+ * confirmation card edits before confirmEvent writes it to Google Calendar.
10
+ */
11
+ exports.EventDraftSchema = zod_1.z.object({
12
+ title: zod_1.z.string().min(1).max(200),
13
+ start: primitives_1.rfc3339,
14
+ end: primitives_1.rfc3339.optional().nullable(),
15
+ timeZone: primitives_1.ianaTimeZone,
16
+ allDay: zod_1.z.boolean().default(false),
17
+ location: zod_1.z.string().max(500).optional().nullable(),
18
+ notes: zod_1.z.string().max(2000).optional().nullable(),
19
+ confidence: zod_1.z.enum(enums_1.CONFIDENCE_LEVELS),
20
+ ambiguities: zod_1.z.array(zod_1.z.string()).default([]),
21
+ /**
22
+ * TTS string read back to the user — generated in the same LLM call so there
23
+ * is no second LLM call per capture (README §4).
24
+ */
25
+ spokenConfirmation: zod_1.z.string().min(1),
26
+ });
27
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/schemas/event.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,mCAA4C;AAC5C,6CAAqD;AAErD;;;GAGG;AACU,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,KAAK,EAAE,oBAAO;IACd,GAAG,EAAE,oBAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAClC,QAAQ,EAAE,yBAAY;IACtB,MAAM,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAClC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACnD,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,yBAAiB,CAAC;IACrC,WAAW,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C;;;OAGG;IACH,kBAAkB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACtC,CAAC,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * `families/{familyId}/members/{memberId}` (README §3).
4
+ * Note: `googleUserId` stores the Firebase Auth UID — NOT Google's `sub`.
5
+ * The uid → (familyId, memberId) mapping lives in `userProfiles/{uid}`.
6
+ */
7
+ export declare const MemberProfileSchema: z.ZodObject<{
8
+ displayName: z.ZodString;
9
+ colorId: z.ZodString;
10
+ /** Built-in illustration-library id (DigitalAvatar decision, README §3). */
11
+ avatarId: z.ZodString;
12
+ authType: z.ZodEnum<["google", "profile"]>;
13
+ /** Firebase Auth UID; null for login-less profile members. */
14
+ googleUserId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
15
+ /** Optional per-member forwarding alias for email intake. */
16
+ intakeEmail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ /** Who created this profile (admin member id), if authType === "profile". */
18
+ createdBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ language: z.ZodString;
20
+ timeZone: z.ZodString;
21
+ voiceId: z.ZodString;
22
+ voiceStylePreset: z.ZodEnum<["professional", "warm_casual", "friendly_brief"]>;
23
+ /** Primary first, fallback after — NOT fan-out (README §5a). */
24
+ notifyChannels: z.ZodArray<z.ZodEnum<["sms", "whatsapp", "telegram"]>, "many">;
25
+ channelStatus: z.ZodRecord<z.ZodEnum<["sms", "whatsapp", "telegram"]>, z.ZodEnum<["opted_in", "pending", "failed"]>>;
26
+ phoneNumber: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ telegramChatId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ timeZone: string;
30
+ displayName: string;
31
+ colorId: string;
32
+ avatarId: string;
33
+ authType: "google" | "profile";
34
+ language: string;
35
+ voiceId: string;
36
+ voiceStylePreset: "professional" | "warm_casual" | "friendly_brief";
37
+ notifyChannels: ("sms" | "whatsapp" | "telegram")[];
38
+ channelStatus: Partial<Record<"sms" | "whatsapp" | "telegram", "opted_in" | "pending" | "failed">>;
39
+ googleUserId?: string | null | undefined;
40
+ intakeEmail?: string | null | undefined;
41
+ createdBy?: string | null | undefined;
42
+ phoneNumber?: string | null | undefined;
43
+ telegramChatId?: string | null | undefined;
44
+ }, {
45
+ timeZone: string;
46
+ displayName: string;
47
+ colorId: string;
48
+ avatarId: string;
49
+ authType: "google" | "profile";
50
+ language: string;
51
+ voiceId: string;
52
+ voiceStylePreset: "professional" | "warm_casual" | "friendly_brief";
53
+ notifyChannels: ("sms" | "whatsapp" | "telegram")[];
54
+ channelStatus: Partial<Record<"sms" | "whatsapp" | "telegram", "opted_in" | "pending" | "failed">>;
55
+ googleUserId?: string | null | undefined;
56
+ intakeEmail?: string | null | undefined;
57
+ createdBy?: string | null | undefined;
58
+ phoneNumber?: string | null | undefined;
59
+ telegramChatId?: string | null | undefined;
60
+ }>;
61
+ /** `userProfiles/{firebaseUid}` — O(1) uid → (familyId, memberId) auth mapping. */
62
+ export declare const UserProfileSchema: z.ZodObject<{
63
+ familyId: z.ZodString;
64
+ memberId: z.ZodString;
65
+ authType: z.ZodEnum<["google", "profile"]>;
66
+ createdAt: z.ZodAny;
67
+ }, "strip", z.ZodTypeAny, {
68
+ authType: "google" | "profile";
69
+ familyId: string;
70
+ memberId: string;
71
+ createdAt?: any;
72
+ }, {
73
+ authType: "google" | "profile";
74
+ familyId: string;
75
+ memberId: string;
76
+ createdAt?: any;
77
+ }>;
78
+ export type MemberProfile = z.infer<typeof MemberProfileSchema>;
79
+ export type UserProfile = z.infer<typeof UserProfileSchema>;
80
+ //# sourceMappingURL=member.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../../src/schemas/member.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;IAG9B,4EAA4E;;;IAG5E,8DAA8D;;IAE9D,6DAA6D;;IAE7D,6EAA6E;;;;;;IAM7E,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKhE,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;EAK5B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserProfileSchema = exports.MemberProfileSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const enums_1 = require("./enums");
6
+ const primitives_1 = require("./primitives");
7
+ /**
8
+ * `families/{familyId}/members/{memberId}` (README §3).
9
+ * Note: `googleUserId` stores the Firebase Auth UID — NOT Google's `sub`.
10
+ * The uid → (familyId, memberId) mapping lives in `userProfiles/{uid}`.
11
+ */
12
+ exports.MemberProfileSchema = zod_1.z.object({
13
+ displayName: zod_1.z.string().min(1).max(100),
14
+ colorId: primitives_1.calendarColorId,
15
+ /** Built-in illustration-library id (DigitalAvatar decision, README §3). */
16
+ avatarId: zod_1.z.string().min(1),
17
+ authType: zod_1.z.enum(enums_1.AUTH_TYPES),
18
+ /** Firebase Auth UID; null for login-less profile members. */
19
+ googleUserId: zod_1.z.string().nullish(),
20
+ /** Optional per-member forwarding alias for email intake. */
21
+ intakeEmail: zod_1.z.string().email().nullish(),
22
+ /** Who created this profile (admin member id), if authType === "profile". */
23
+ createdBy: zod_1.z.string().nullish(),
24
+ language: primitives_1.bcp47Language,
25
+ timeZone: primitives_1.ianaTimeZone,
26
+ voiceId: zod_1.z.string().min(1),
27
+ voiceStylePreset: zod_1.z.enum(enums_1.VOICE_STYLE_PRESETS),
28
+ /** Primary first, fallback after — NOT fan-out (README §5a). */
29
+ notifyChannels: zod_1.z.array(zod_1.z.enum(enums_1.NOTIFY_CHANNELS)).min(1),
30
+ channelStatus: zod_1.z.record(zod_1.z.enum(enums_1.NOTIFY_CHANNELS), zod_1.z.enum(enums_1.CHANNEL_STATUSES)),
31
+ phoneNumber: primitives_1.e164Phone.nullish(),
32
+ telegramChatId: zod_1.z.string().nullish(),
33
+ });
34
+ /** `userProfiles/{firebaseUid}` — O(1) uid → (familyId, memberId) auth mapping. */
35
+ exports.UserProfileSchema = zod_1.z.object({
36
+ familyId: zod_1.z.string().min(1),
37
+ memberId: zod_1.z.string().min(1),
38
+ authType: zod_1.z.enum(enums_1.AUTH_TYPES),
39
+ createdAt: primitives_1.firestoreTimestamp,
40
+ });
41
+ //# sourceMappingURL=member.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member.js","sourceRoot":"","sources":["../../src/schemas/member.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,mCAA6F;AAC7F,6CAMsB;AAEtB;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvC,OAAO,EAAE,4BAAe;IACxB,4EAA4E;IAC5E,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,QAAQ,EAAE,OAAC,CAAC,IAAI,CAAC,kBAAU,CAAC;IAC5B,8DAA8D;IAC9D,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IAClC,6DAA6D;IAC7D,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE;IACzC,6EAA6E;IAC7E,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IAC/B,QAAQ,EAAE,0BAAa;IACvB,QAAQ,EAAE,yBAAY;IACtB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,gBAAgB,EAAE,OAAC,CAAC,IAAI,CAAC,2BAAmB,CAAC;IAC7C,gEAAgE;IAChE,cAAc,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC,uBAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,aAAa,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,IAAI,CAAC,uBAAe,CAAC,EAAE,OAAC,CAAC,IAAI,CAAC,wBAAgB,CAAC,CAAC;IAC1E,WAAW,EAAE,sBAAS,CAAC,OAAO,EAAE;IAChC,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;CACrC,CAAC,CAAC;AAEH,mFAAmF;AACtE,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,QAAQ,EAAE,OAAC,CAAC,IAAI,CAAC,kBAAU,CAAC;IAC5B,SAAS,EAAE,+BAAkB;CAC9B,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ /** RFC3339 timestamp with timezone offset, e.g. "2026-09-08T15:00:00+08:00". */
3
+ export declare const rfc3339: z.ZodString;
4
+ /** IANA timezone name, light-validated (Region/City shape). */
5
+ export declare const ianaTimeZone: z.ZodString;
6
+ /** Loose BCP-47 language tag, e.g. en-US, zh-CN, es-MX. */
7
+ export declare const bcp47Language: z.ZodString;
8
+ /** E.164 phone number, e.g. +14155552671. */
9
+ export declare const e164Phone: z.ZodString;
10
+ /** Google Calendar color id "1"–"11". */
11
+ export declare const calendarColorId: z.ZodString;
12
+ /**
13
+ * Firestore server timestamp — intentionally loose in the shared layer
14
+ * (a JS Date in the app, a firestore Timestamp in Cloud Functions).
15
+ */
16
+ export declare const firestoreTimestamp: z.ZodAny;
17
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/schemas/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gFAAgF;AAChF,eAAO,MAAM,OAAO,aAAwC,CAAC;AAE7D,+DAA+D;AAC/D,eAAO,MAAM,YAAY,aAA0D,CAAC;AAEpF,2DAA2D;AAC3D,eAAO,MAAM,aAAa,aAA0D,CAAC;AAErF,6CAA6C;AAC7C,eAAO,MAAM,SAAS,aAAwC,CAAC;AAE/D,yCAAyC;AACzC,eAAO,MAAM,eAAe,aAAsC,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAU,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.firestoreTimestamp = exports.calendarColorId = exports.e164Phone = exports.bcp47Language = exports.ianaTimeZone = exports.rfc3339 = void 0;
4
+ const zod_1 = require("zod");
5
+ /** RFC3339 timestamp with timezone offset, e.g. "2026-09-08T15:00:00+08:00". */
6
+ exports.rfc3339 = zod_1.z.string().datetime({ offset: true });
7
+ /** IANA timezone name, light-validated (Region/City shape). */
8
+ exports.ianaTimeZone = zod_1.z.string().regex(/^[A-Za-z]{2,}(\/[A-Za-z0-9_+\-]+)+$/);
9
+ /** Loose BCP-47 language tag, e.g. en-US, zh-CN, es-MX. */
10
+ exports.bcp47Language = zod_1.z.string().regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/i);
11
+ /** E.164 phone number, e.g. +14155552671. */
12
+ exports.e164Phone = zod_1.z.string().regex(/^\+[1-9]\d{1,14}$/);
13
+ /** Google Calendar color id "1"–"11". */
14
+ exports.calendarColorId = zod_1.z.string().regex(/^(1[01]|[1-9])$/);
15
+ /**
16
+ * Firestore server timestamp — intentionally loose in the shared layer
17
+ * (a JS Date in the app, a firestore Timestamp in Cloud Functions).
18
+ */
19
+ exports.firestoreTimestamp = zod_1.z.any();
20
+ //# sourceMappingURL=primitives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/schemas/primitives.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,gFAAgF;AACnE,QAAA,OAAO,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAE7D,+DAA+D;AAClD,QAAA,YAAY,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;AAEpF,2DAA2D;AAC9C,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;AAErF,6CAA6C;AAChC,QAAA,SAAS,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAE/D,yCAAyC;AAC5B,QAAA,eAAe,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAEnE;;;GAGG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * `families/{familyId}/sentReminders/{eventId}_{offsetMinutes}_{channel}`
4
+ * (README §3, §5a). The deterministic doc id + create-if-absent write means
5
+ * overlapping scheduled runs and function retries can never double-send.
6
+ */
7
+ export declare const SentReminderSchema: z.ZodObject<{
8
+ eventId: z.ZodString;
9
+ offsetMinutes: z.ZodNumber;
10
+ sentAt: z.ZodOptional<z.ZodAny>;
11
+ channel: z.ZodEnum<["sms", "whatsapp", "telegram"]>;
12
+ status: z.ZodEnum<["sent", "failed", "skipped"]>;
13
+ attempt: z.ZodDefault<z.ZodNumber>;
14
+ lastError: z.ZodDefault<z.ZodNullable<z.ZodString>>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ status: "failed" | "sent" | "skipped";
17
+ eventId: string;
18
+ offsetMinutes: number;
19
+ channel: "sms" | "whatsapp" | "telegram";
20
+ attempt: number;
21
+ lastError: string | null;
22
+ sentAt?: any;
23
+ }, {
24
+ status: "failed" | "sent" | "skipped";
25
+ eventId: string;
26
+ offsetMinutes: number;
27
+ channel: "sms" | "whatsapp" | "telegram";
28
+ sentAt?: any;
29
+ attempt?: number | undefined;
30
+ lastError?: string | null | undefined;
31
+ }>;
32
+ export type SentReminder = z.infer<typeof SentReminderSchema>;
33
+ //# sourceMappingURL=reminder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminder.d.ts","sourceRoot":"","sources":["../../src/schemas/reminder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;EAQ7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SentReminderSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const enums_1 = require("./enums");
6
+ const primitives_1 = require("./primitives");
7
+ /**
8
+ * `families/{familyId}/sentReminders/{eventId}_{offsetMinutes}_{channel}`
9
+ * (README §3, §5a). The deterministic doc id + create-if-absent write means
10
+ * overlapping scheduled runs and function retries can never double-send.
11
+ */
12
+ exports.SentReminderSchema = zod_1.z.object({
13
+ eventId: zod_1.z.string().min(1),
14
+ offsetMinutes: zod_1.z.number().int().positive(),
15
+ sentAt: primitives_1.firestoreTimestamp.optional(),
16
+ channel: zod_1.z.enum(enums_1.NOTIFY_CHANNELS),
17
+ status: zod_1.z.enum(enums_1.REMINDER_STATUSES),
18
+ attempt: zod_1.z.number().int().nonnegative().default(0),
19
+ lastError: zod_1.z.string().nullable().default(null),
20
+ });
21
+ //# sourceMappingURL=reminder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminder.js","sourceRoot":"","sources":["../../src/schemas/reminder.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,mCAA6D;AAC7D,6CAAkD;AAElD;;;;GAIG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC1C,MAAM,EAAE,+BAAkB,CAAC,QAAQ,EAAE;IACrC,OAAO,EAAE,OAAC,CAAC,IAAI,CAAC,uBAAe,CAAC;IAChC,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,yBAAiB,CAAC;IACjC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CAC/C,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@voxendar/shared",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "Shared contracts, schemas, constants and pure logic for Voxendar/Tellie (consumed by functions/ and app/)",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc -p tsconfig.json",
13
+ "typecheck": "tsc --noEmit -p tsconfig.json",
14
+ "test": "vitest run"
15
+ },
16
+ "dependencies": {
17
+ "zod": "^3.23.8"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^20.14.0",
21
+ "typescript": "^5.5.4",
22
+ "vitest": "^2.1.9"
23
+ }
24
+ }