@unisonlabs/sixminute-admin 0.1.1233-next → 0.1.1234
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/dist/sixminute-admin.mjs +180 -20
- package/package.json +1 -1
package/dist/sixminute-admin.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import { homedir } from "node:os";
|
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
22
|
|
|
23
23
|
// tools/admin/src/build-info.ts
|
|
24
|
-
var BUILT = { version: "0.1.
|
|
24
|
+
var BUILT = { version: "0.1.1234", commit: "87eb8615276920192e16568312a53f1302621d8e", surface: "daa5005ac9ba21da" };
|
|
25
25
|
|
|
26
26
|
// tools/admin/src/run.ts
|
|
27
27
|
import { rmSync as rmSync3 } from "node:fs";
|
|
@@ -4356,6 +4356,39 @@ var ActivityTypeSchema = exports_external.object({
|
|
|
4356
4356
|
});
|
|
4357
4357
|
var JudgmentPipelineSchema = exports_external.enum(["standard", "jev"]);
|
|
4358
4358
|
|
|
4359
|
+
// packages/contracts/src/grid.ts
|
|
4360
|
+
var UNIT_MINUTES = [3, 5, 6, 10, 12, 15];
|
|
4361
|
+
var UNIT_MIN = UNIT_MINUTES[0];
|
|
4362
|
+
var UNIT_MAX = UNIT_MINUTES[UNIT_MINUTES.length - 1];
|
|
4363
|
+
var UnitMinutesSchema = exports_external.number().int().min(UNIT_MIN).max(UNIT_MAX).refine((minutes) => !Number.isInteger(minutes) || minutes < UNIT_MIN || minutes > UNIT_MAX || UNIT_MINUTES.includes(minutes), { message: `an interval is one of ${UNIT_MINUTES.join(", ")} minutes, a divisor of the hour` });
|
|
4364
|
+
var WALL_CLOCKS = new Map;
|
|
4365
|
+
function wallClockFormat(zone) {
|
|
4366
|
+
const kept = WALL_CLOCKS.get(zone);
|
|
4367
|
+
if (kept !== undefined)
|
|
4368
|
+
return kept;
|
|
4369
|
+
const format = new Intl.DateTimeFormat("en-US", {
|
|
4370
|
+
timeZone: zone,
|
|
4371
|
+
hourCycle: "h23",
|
|
4372
|
+
year: "numeric",
|
|
4373
|
+
month: "2-digit",
|
|
4374
|
+
day: "2-digit",
|
|
4375
|
+
hour: "2-digit",
|
|
4376
|
+
minute: "2-digit",
|
|
4377
|
+
second: "2-digit"
|
|
4378
|
+
});
|
|
4379
|
+
WALL_CLOCKS.set(zone, format);
|
|
4380
|
+
return format;
|
|
4381
|
+
}
|
|
4382
|
+
function wallClock(ms, zone) {
|
|
4383
|
+
const parts = wallClockFormat(zone).formatToParts(new Date(ms));
|
|
4384
|
+
const part = (type) => Number(parts.find((p) => p.type === type).value);
|
|
4385
|
+
const wholeSeconds = Date.UTC(part("year"), part("month") - 1, part("day"), part("hour"), part("minute"), part("second"));
|
|
4386
|
+
return wholeSeconds + (ms - Math.floor(ms / 1000) * 1000);
|
|
4387
|
+
}
|
|
4388
|
+
function dayOf(iso, zone) {
|
|
4389
|
+
return new Date(wallClock(Date.parse(iso), zone)).toISOString().slice(0, 10);
|
|
4390
|
+
}
|
|
4391
|
+
|
|
4359
4392
|
// packages/contracts/src/entry.ts
|
|
4360
4393
|
var EntryStatusSchema = exports_external.enum(["draft", "released"]);
|
|
4361
4394
|
var AssignmentSchema = exports_external.enum(["model", "user", "none"]);
|
|
@@ -4370,6 +4403,12 @@ var NarrativeSchema = exports_external.string().transform((s) => s.trim()).super
|
|
|
4370
4403
|
});
|
|
4371
4404
|
}
|
|
4372
4405
|
});
|
|
4406
|
+
var EntryPartSchema = exports_external.object({
|
|
4407
|
+
t_start: TimestampSchema,
|
|
4408
|
+
t_end: TimestampSchema
|
|
4409
|
+
}).refine((part) => part.t_start < part.t_end, { path: ["t_end"], message: "a part ends after it starts" });
|
|
4410
|
+
var OVERRIDE_MAX_SECONDS = 86400;
|
|
4411
|
+
var OverrideSecondsSchema = exports_external.number().int().positive().max(OVERRIDE_MAX_SECONDS).refine((seconds) => seconds % 60 === 0, { message: "an override is a whole number of minutes" });
|
|
4373
4412
|
var EntryContentFields = exports_external.object({
|
|
4374
4413
|
id: EntryIdSchema,
|
|
4375
4414
|
day: LocalDaySchema,
|
|
@@ -4377,6 +4416,7 @@ var EntryContentFields = exports_external.object({
|
|
|
4377
4416
|
timekeeper_id: exports_external.string().min(1),
|
|
4378
4417
|
t_start: TimestampSchema,
|
|
4379
4418
|
t_end: TimestampSchema,
|
|
4419
|
+
parts: exports_external.array(EntryPartSchema).min(1).optional(),
|
|
4380
4420
|
narrative: NarrativeSchema,
|
|
4381
4421
|
matter_id: MatterIdSchema.nullable().default(null),
|
|
4382
4422
|
attributes: EntryAttributesSchema.default({}),
|
|
@@ -4398,10 +4438,13 @@ var AsJudgedSchema = EntryContentFields.omit({
|
|
|
4398
4438
|
});
|
|
4399
4439
|
var AS_JUDGED_FIELDS = Object.keys(AsJudgedSchema.shape);
|
|
4400
4440
|
var EntryFields = EntryContentFields.extend({
|
|
4401
|
-
edited_at: TimestampSchema.nullable().default(null)
|
|
4441
|
+
edited_at: TimestampSchema.nullable().default(null),
|
|
4442
|
+
override_seconds: OverrideSecondsSchema.nullable().optional()
|
|
4402
4443
|
});
|
|
4403
4444
|
var JudgedEntryFields = EntryFields.extend({
|
|
4404
|
-
as_judged: AsJudgedSchema.
|
|
4445
|
+
as_judged: AsJudgedSchema.superRefine((copy, ctx) => {
|
|
4446
|
+
refineParts(copy, ctx);
|
|
4447
|
+
}).nullable().default(null)
|
|
4405
4448
|
});
|
|
4406
4449
|
function refineEntry(entry, ctx) {
|
|
4407
4450
|
if (entry.status !== "draft" && entry.released_at === null) {
|
|
@@ -4418,9 +4461,58 @@ function refineEntry(entry, ctx) {
|
|
|
4418
4461
|
message: "the block ends after it starts"
|
|
4419
4462
|
});
|
|
4420
4463
|
}
|
|
4464
|
+
refineParts(entry, ctx);
|
|
4421
4465
|
}
|
|
4422
|
-
|
|
4423
|
-
|
|
4466
|
+
function refineParts(entry, ctx) {
|
|
4467
|
+
const parts = entry.parts;
|
|
4468
|
+
if (parts === undefined || parts.length === 0)
|
|
4469
|
+
return;
|
|
4470
|
+
parts.forEach((part, index) => {
|
|
4471
|
+
const previous = parts[index - 1];
|
|
4472
|
+
if (previous !== undefined && part.t_start <= previous.t_end) {
|
|
4473
|
+
ctx.addIssue({
|
|
4474
|
+
code: exports_external.ZodIssueCode.custom,
|
|
4475
|
+
path: ["parts", index, "t_start"],
|
|
4476
|
+
message: part.t_start === previous.t_end ? "parts that touch are one part: join them" : "the parts are in time order and do not overlap: this one starts before the one before it ends"
|
|
4477
|
+
});
|
|
4478
|
+
}
|
|
4479
|
+
});
|
|
4480
|
+
if (parts.length < 2)
|
|
4481
|
+
return;
|
|
4482
|
+
if (parts[0].t_start !== entry.t_start) {
|
|
4483
|
+
ctx.addIssue({
|
|
4484
|
+
code: exports_external.ZodIssueCode.custom,
|
|
4485
|
+
path: ["t_start"],
|
|
4486
|
+
message: "t_start is the first part's start"
|
|
4487
|
+
});
|
|
4488
|
+
}
|
|
4489
|
+
if (parts[parts.length - 1].t_end !== entry.t_end) {
|
|
4490
|
+
ctx.addIssue({
|
|
4491
|
+
code: exports_external.ZodIssueCode.custom,
|
|
4492
|
+
path: ["t_end"],
|
|
4493
|
+
message: "t_end is the last part's end"
|
|
4494
|
+
});
|
|
4495
|
+
}
|
|
4496
|
+
parts.forEach((part, index) => {
|
|
4497
|
+
if (!partOnDay(part, entry.day, entry.time_zone)) {
|
|
4498
|
+
ctx.addIssue({
|
|
4499
|
+
code: exports_external.ZodIssueCode.custom,
|
|
4500
|
+
path: ["parts", index],
|
|
4501
|
+
message: `every part lies on the entry's day, ${entry.day} in ${entry.time_zone}, and never crosses midnight`
|
|
4502
|
+
});
|
|
4503
|
+
}
|
|
4504
|
+
});
|
|
4505
|
+
}
|
|
4506
|
+
function settleEntry(entry, ctx) {
|
|
4507
|
+
refineEntry(entry, ctx);
|
|
4508
|
+
return {
|
|
4509
|
+
...entry,
|
|
4510
|
+
parts: entry.parts !== undefined && entry.parts.length > 1 ? entry.parts : [{ t_start: entry.t_start, t_end: entry.t_end }],
|
|
4511
|
+
override_seconds: entry.override_seconds ?? null
|
|
4512
|
+
};
|
|
4513
|
+
}
|
|
4514
|
+
var EntrySchema = EntryFields.transform(settleEntry);
|
|
4515
|
+
var JudgedEntrySchema = JudgedEntryFields.transform(settleEntry);
|
|
4424
4516
|
var RecordingFields = {
|
|
4425
4517
|
idle_ratio: exports_external.number().min(0).max(1).default(0),
|
|
4426
4518
|
observation_ids: exports_external.array(ObservationIdSchema).default([]),
|
|
@@ -4429,8 +4521,23 @@ var RecordingFields = {
|
|
|
4429
4521
|
assigned_at: TimestampSchema.nullable().default(null),
|
|
4430
4522
|
recording_id: RecordingIdSchema.nullable().default(null)
|
|
4431
4523
|
};
|
|
4432
|
-
var RecordingEntrySchema = JudgedEntryFields.extend(RecordingFields).
|
|
4524
|
+
var RecordingEntrySchema = JudgedEntryFields.extend(RecordingFields).transform(settleEntry);
|
|
4433
4525
|
var RECORDING_ENTRY_FIELDS = Object.keys(RecordingFields);
|
|
4526
|
+
function partsOf(entry) {
|
|
4527
|
+
const parts = entry.parts;
|
|
4528
|
+
const block = [{ t_start: entry.t_start, t_end: entry.t_end }];
|
|
4529
|
+
if (parts === undefined || parts.length === 0)
|
|
4530
|
+
return block;
|
|
4531
|
+
const bounded = Date.parse(parts[0].t_start) === Date.parse(entry.t_start) && Date.parse(parts[parts.length - 1].t_end) === Date.parse(entry.t_end);
|
|
4532
|
+
return bounded ? parts : block;
|
|
4533
|
+
}
|
|
4534
|
+
function partOnDay(part, day, zone) {
|
|
4535
|
+
try {
|
|
4536
|
+
return dayOf(part.t_start, zone) === day && dayOf(new Date(Date.parse(part.t_end) - 1).toISOString(), zone) === day;
|
|
4537
|
+
} catch {
|
|
4538
|
+
return false;
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4434
4541
|
|
|
4435
4542
|
// packages/contracts/src/connector.ts
|
|
4436
4543
|
var ConnectorKindSchema = exports_external.enum(["urios", "legalsense", "partner", "fake"]);
|
|
@@ -4863,13 +4970,6 @@ var IntervalTextSchema = exports_external.object({
|
|
|
4863
4970
|
entries: exports_external.array(IntervalTextEntrySchema).optional()
|
|
4864
4971
|
});
|
|
4865
4972
|
|
|
4866
|
-
// packages/contracts/src/grid.ts
|
|
4867
|
-
var UNIT_MINUTES = [3, 5, 6, 10, 12, 15];
|
|
4868
|
-
var UNIT_MIN = UNIT_MINUTES[0];
|
|
4869
|
-
var UNIT_MAX = UNIT_MINUTES[UNIT_MINUTES.length - 1];
|
|
4870
|
-
var UnitMinutesSchema = exports_external.number().int().min(UNIT_MIN).max(UNIT_MAX).refine((minutes) => !Number.isInteger(minutes) || minutes < UNIT_MIN || minutes > UNIT_MAX || UNIT_MINUTES.includes(minutes), { message: `an interval is one of ${UNIT_MINUTES.join(", ")} minutes, a divisor of the hour` });
|
|
4871
|
-
var WALL_CLOCKS = new Map;
|
|
4872
|
-
|
|
4873
4973
|
// packages/contracts/src/api.ts
|
|
4874
4974
|
var ProblemSchema = exports_external.object({
|
|
4875
4975
|
type: exports_external.string().min(1),
|
|
@@ -5154,6 +5254,8 @@ var EntryPatchSchema = exports_external.object({
|
|
|
5154
5254
|
matter_id: EntrySchema.innerType().shape.matter_id.optional(),
|
|
5155
5255
|
t_start: TimestampSchema.optional(),
|
|
5156
5256
|
t_end: TimestampSchema.optional(),
|
|
5257
|
+
parts: exports_external.array(EntryPartSchema).min(1).optional(),
|
|
5258
|
+
override_seconds: OverrideSecondsSchema.nullable().optional(),
|
|
5157
5259
|
reason: exports_external.string().min(1).nullable().default(null)
|
|
5158
5260
|
}).superRefine((patch, ctx) => {
|
|
5159
5261
|
const hasStart = patch.t_start !== undefined;
|
|
@@ -5165,6 +5267,27 @@ var EntryPatchSchema = exports_external.object({
|
|
|
5165
5267
|
message: "a block is a pair: send t_start and t_end together"
|
|
5166
5268
|
});
|
|
5167
5269
|
}
|
|
5270
|
+
if (patch.parts !== undefined && (hasStart || hasEnd)) {
|
|
5271
|
+
ctx.addIssue({
|
|
5272
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5273
|
+
path: ["parts"],
|
|
5274
|
+
message: "parts replace the block: send parts or t_start and t_end, not both"
|
|
5275
|
+
});
|
|
5276
|
+
}
|
|
5277
|
+
if (patch.parts !== undefined && patch.override_seconds !== undefined) {
|
|
5278
|
+
ctx.addIssue({
|
|
5279
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5280
|
+
path: ["override_seconds"],
|
|
5281
|
+
message: "a change to the parts clears the override: send parts or override_seconds, not both"
|
|
5282
|
+
});
|
|
5283
|
+
}
|
|
5284
|
+
if ((hasStart || hasEnd) && patch.override_seconds !== undefined) {
|
|
5285
|
+
ctx.addIssue({
|
|
5286
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5287
|
+
path: ["override_seconds"],
|
|
5288
|
+
message: "a move of the block clears the override: send t_start and t_end or override_seconds, not both"
|
|
5289
|
+
});
|
|
5290
|
+
}
|
|
5168
5291
|
});
|
|
5169
5292
|
var ConfirmedNarrativeSchema = EntrySchema.innerType().shape.narrative.refine((narrative) => narrative.length > 0, { message: "a confirmed narrative is not empty: this is the line the person read and approved" });
|
|
5170
5293
|
var EntryHalfSchema = exports_external.object({
|
|
@@ -5173,10 +5296,18 @@ var EntryHalfSchema = exports_external.object({
|
|
|
5173
5296
|
attributes: EntryAttributesSchema
|
|
5174
5297
|
});
|
|
5175
5298
|
var EntrySplitRequestSchema = exports_external.object({
|
|
5176
|
-
at: TimestampSchema,
|
|
5299
|
+
at: TimestampSchema.optional(),
|
|
5300
|
+
leaving: exports_external.array(EntryPartSchema).min(1).optional(),
|
|
5177
5301
|
first: EntryHalfSchema.optional(),
|
|
5178
5302
|
second: EntryHalfSchema.optional()
|
|
5179
5303
|
}).superRefine((body, ctx) => {
|
|
5304
|
+
if (body.at === undefined === (body.leaving === undefined)) {
|
|
5305
|
+
ctx.addIssue({
|
|
5306
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5307
|
+
path: ["leaving"],
|
|
5308
|
+
message: "a split names a line in `at` or the parts that leave in `leaving`, and exactly one of them"
|
|
5309
|
+
});
|
|
5310
|
+
}
|
|
5180
5311
|
if (body.first === undefined !== (body.second === undefined)) {
|
|
5181
5312
|
ctx.addIssue({
|
|
5182
5313
|
code: exports_external.ZodIssueCode.custom,
|
|
@@ -5215,13 +5346,20 @@ var EntryBatchItemSchema = exports_external.object({
|
|
|
5215
5346
|
entry: JudgedEntrySchema,
|
|
5216
5347
|
intervals: exports_external.array(IntervalSchema).default([])
|
|
5217
5348
|
}).superRefine((item, ctx) => {
|
|
5218
|
-
|
|
5349
|
+
if (item.entry.override_seconds != null) {
|
|
5350
|
+
ctx.addIssue({
|
|
5351
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5352
|
+
path: ["entry", "override_seconds"],
|
|
5353
|
+
message: "a batch row carries no override: a person sets one on the entry's PATCH"
|
|
5354
|
+
});
|
|
5355
|
+
}
|
|
5356
|
+
const parts = partsOf(item.entry);
|
|
5219
5357
|
item.intervals.forEach((interval, index) => {
|
|
5220
|
-
if (
|
|
5358
|
+
if (!parts.some((part) => part.t_start <= interval.t_start && interval.t_end <= part.t_end)) {
|
|
5221
5359
|
ctx.addIssue({
|
|
5222
5360
|
code: exports_external.ZodIssueCode.custom,
|
|
5223
5361
|
path: ["intervals", index],
|
|
5224
|
-
message: `an interval lies inside its entry's
|
|
5362
|
+
message: `an interval lies inside one of its entry's parts: this one covers ${interval.t_start} to ${interval.t_end}, and the parts ${parts.map((part) => `${part.t_start} to ${part.t_end}`).join(", ")}`
|
|
5225
5363
|
});
|
|
5226
5364
|
return;
|
|
5227
5365
|
}
|
|
@@ -5650,6 +5788,8 @@ var JudgedPairEntrySchema = exports_external.object({
|
|
|
5650
5788
|
timekeeper_id: exports_external.string(),
|
|
5651
5789
|
t_start: exports_external.string(),
|
|
5652
5790
|
t_end: exports_external.string(),
|
|
5791
|
+
parts: exports_external.array(exports_external.object({ t_start: exports_external.string(), t_end: exports_external.string() })).nullable().default(null),
|
|
5792
|
+
override_seconds: exports_external.number().int().nullable().default(null),
|
|
5653
5793
|
narrative: exports_external.string(),
|
|
5654
5794
|
matter_id: exports_external.string().nullable(),
|
|
5655
5795
|
attributes: exports_external.unknown(),
|
|
@@ -6264,9 +6404,29 @@ var LocalRecordingStopSchema = exports_external.object({
|
|
|
6264
6404
|
seconds: exports_external.number().nonnegative()
|
|
6265
6405
|
});
|
|
6266
6406
|
var LocalAcceptedSchema = exports_external.object({ accepted: exports_external.literal(true) });
|
|
6267
|
-
var LocalProposeRangeSchema = exports_external.object({
|
|
6268
|
-
|
|
6269
|
-
|
|
6407
|
+
var LocalProposeRangeSchema = exports_external.object({
|
|
6408
|
+
from: TimestampSchema,
|
|
6409
|
+
to: TimestampSchema,
|
|
6410
|
+
matter_id: MatterIdSchema.optional(),
|
|
6411
|
+
parts: exports_external.array(exports_external.object({ from: TimestampSchema, to: TimestampSchema })).min(1).optional()
|
|
6412
|
+
}).superRefine((range, ctx) => {
|
|
6413
|
+
if (!(Date.parse(range.from) < Date.parse(range.to))) {
|
|
6414
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["to"], message: "a range ends after it starts" });
|
|
6415
|
+
}
|
|
6416
|
+
range.parts?.forEach((part, index) => {
|
|
6417
|
+
const previous = range.parts[index - 1];
|
|
6418
|
+
if (!(Date.parse(part.from) < Date.parse(part.to))) {
|
|
6419
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["parts", index, "to"], message: "a part ends after it starts" });
|
|
6420
|
+
} else if (Date.parse(part.from) < Date.parse(range.from) || Date.parse(part.to) > Date.parse(range.to)) {
|
|
6421
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["parts", index], message: "a part lies inside its range" });
|
|
6422
|
+
} else if (previous !== undefined && Date.parse(part.from) <= Date.parse(previous.to)) {
|
|
6423
|
+
ctx.addIssue({
|
|
6424
|
+
code: exports_external.ZodIssueCode.custom,
|
|
6425
|
+
path: ["parts", index, "from"],
|
|
6426
|
+
message: "the parts are in time order and neither touch nor overlap"
|
|
6427
|
+
});
|
|
6428
|
+
}
|
|
6429
|
+
});
|
|
6270
6430
|
});
|
|
6271
6431
|
var LocalProposeRangesRequestSchema = exports_external.object({
|
|
6272
6432
|
ranges: exports_external.array(LocalProposeRangeSchema).min(1).max(2)
|
package/package.json
CHANGED