@updraft-solutions/mcrit-sdk 0.14.11 → 0.14.13
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/{chunk-FNIZXT5C.cjs → chunk-DV2IZVDB.cjs} +102 -1
- package/dist/{chunk-RUNBP37X.js → chunk-LL3XK7X2.js} +102 -1
- package/dist/{fbo-DlZNor1r.d.cts → fbo-sWpm3mI6.d.cts} +17311 -16771
- package/dist/{fbo-DlZNor1r.d.ts → fbo-sWpm3mI6.d.ts} +17311 -16771
- package/dist/index.cjs +26 -6
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +33 -13
- package/dist/schemas/index.cjs +22 -2
- package/dist/schemas/index.d.cts +121 -121
- package/dist/schemas/index.d.ts +121 -121
- package/dist/schemas/index.js +21 -1
- package/dist/types/index.d.cts +582 -3
- package/dist/types/index.d.ts +582 -3
- package/package.json +1 -1
- package/src/index.ts +43 -0
- package/src/schemas/fbo.spec.ts +228 -0
- package/src/schemas/fbo.ts +170 -0
- package/src/types/fbo.ts +10 -0
- package/dist/operating-hours-CMhR5S8y.d.cts +0 -574
- package/dist/operating-hours-CgEKmXSK.d.ts +0 -574
package/src/schemas/fbo.spec.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
fboActivitySchema,
|
|
4
|
+
fboCompanyGrantSchema,
|
|
4
5
|
fboCompanyMemberSchema,
|
|
6
|
+
fboCompanySchema,
|
|
5
7
|
fboDutyAffectedSchema,
|
|
6
8
|
fboDutySchema,
|
|
7
9
|
fboDutySeriesResponseSchema,
|
|
10
|
+
fboFlightDocumentSchema,
|
|
8
11
|
fboFlightSchema,
|
|
9
12
|
fboFlightStatusSchema,
|
|
13
|
+
fboGrantAbilitySchema,
|
|
10
14
|
fboMaterialiseResultSchema,
|
|
15
|
+
fboMetaSchema,
|
|
11
16
|
fboOccupationSchema,
|
|
12
17
|
fboOperationsSchema,
|
|
18
|
+
fboPersonSchema,
|
|
19
|
+
fboPobSchema,
|
|
13
20
|
fboRecurrenceSchema,
|
|
14
21
|
fboRecurringFlightSchema,
|
|
15
22
|
fboStatisticsSchema,
|
|
@@ -361,3 +368,224 @@ describe("fboMaterialiseResultSchema", () => {
|
|
|
361
368
|
expect(fboMaterialiseResultSchema.parse(payload)).toEqual(payload);
|
|
362
369
|
});
|
|
363
370
|
});
|
|
371
|
+
|
|
372
|
+
const pobPayload = {
|
|
373
|
+
crew: true,
|
|
374
|
+
firstname: "Erika",
|
|
375
|
+
lastname: "Muster",
|
|
376
|
+
birth: "1979-04-02",
|
|
377
|
+
nationality: "DE",
|
|
378
|
+
document_id: "C01X00T47",
|
|
379
|
+
document_validity: "2031-04-01",
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
describe("fboPobSchema", () => {
|
|
383
|
+
it("parses a fully filled person on board", () => {
|
|
384
|
+
expect(fboPobSchema.parse(pobPayload).nationality).toBe("DE");
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("parses a person whose travel document is not known yet — every field but the names is optional data", () => {
|
|
388
|
+
const sparse = { ...pobPayload, birth: null, nationality: null, document_id: null, document_validity: null };
|
|
389
|
+
expect(fboPobSchema.parse(sparse).document_id).toBeNull();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("rejects a missing lastname — the API requires both names on every entry", () => {
|
|
393
|
+
const { lastname, ...withoutLastname } = pobPayload;
|
|
394
|
+
expect(fboPobSchema.safeParse(withoutLastname).success).toBe(false);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it("rejects crew as a string — the flag decides which table half the declaration lists the person in", () => {
|
|
398
|
+
expect(fboPobSchema.safeParse({ ...pobPayload, crew: "1" }).success).toBe(false);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
describe("fboPersonSchema", () => {
|
|
403
|
+
const personPayload = { ...pobPayload, id: 143, is_mine: true, created_at: "2026-08-26T10:00:00.000000Z" };
|
|
404
|
+
|
|
405
|
+
it("parses an address-book row the caller owns", () => {
|
|
406
|
+
const parsed = fboPersonSchema.parse(personPayload);
|
|
407
|
+
expect(parsed.id).toBe(143);
|
|
408
|
+
expect(parsed.is_mine).toBe(true);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it("parses a row visible only through the company, not owned by the caller", () => {
|
|
412
|
+
expect(fboPersonSchema.parse({ ...personPayload, is_mine: false }).is_mine).toBe(false);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it("rejects a row without an id — a template must be addressable to be edited or deleted", () => {
|
|
416
|
+
const { id, ...withoutId } = personPayload;
|
|
417
|
+
expect(fboPersonSchema.safeParse(withoutId).success).toBe(false);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const documentPayload = {
|
|
422
|
+
id: 9001,
|
|
423
|
+
uuid: "6f1b3d5e-0000-4000-8000-000000000042",
|
|
424
|
+
name: "General Declaration",
|
|
425
|
+
file_name: "gendec.pdf",
|
|
426
|
+
mime_type: "application/pdf",
|
|
427
|
+
size: 84213,
|
|
428
|
+
collection_name: "documents",
|
|
429
|
+
ima_file_id: null,
|
|
430
|
+
download_path: "/companies/34/fbo/flights/44796/documents/9001",
|
|
431
|
+
created_at: "2026-08-26T10:00:00.000000Z",
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
describe("fboFlightDocumentSchema", () => {
|
|
435
|
+
it("parses an uploaded movement document", () => {
|
|
436
|
+
expect(fboFlightDocumentSchema.parse(documentPayload).download_path).toBe(
|
|
437
|
+
"/companies/34/fbo/flights/44796/documents/9001",
|
|
438
|
+
);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
it("parses an imported row whose source id is stamped as text", () => {
|
|
442
|
+
expect(fboFlightDocumentSchema.parse({ ...documentPayload, ima_file_id: "104" }).ima_file_id).toBe("104");
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it("rejects a size sent as a string — the list renders it as a byte count", () => {
|
|
446
|
+
expect(fboFlightDocumentSchema.safeParse({ ...documentPayload, size: "84213" }).success).toBe(false);
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
describe("fboFlightSchema — POB, documents and the customs mail stamp", () => {
|
|
451
|
+
it("parses a movement whose payload carries none of the three keys — a colleague never receives POB", () => {
|
|
452
|
+
const parsed = fboFlightSchema.parse(flightPayload);
|
|
453
|
+
expect(parsed.pobs).toBeUndefined();
|
|
454
|
+
expect(parsed.documents_count).toBeUndefined();
|
|
455
|
+
expect(parsed.customs_mail_sent_at).toBeUndefined();
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it("parses the author's own row: the POB list, the document count and an unsent customs mail", () => {
|
|
459
|
+
const own = { ...flightPayload, pobs: [pobPayload], documents_count: 2, customs_mail_sent_at: null };
|
|
460
|
+
const parsed = fboFlightSchema.parse(own);
|
|
461
|
+
expect(parsed.pobs).toHaveLength(1);
|
|
462
|
+
expect(parsed.documents_count).toBe(2);
|
|
463
|
+
expect(parsed.customs_mail_sent_at).toBeNull();
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it("parses pobs: null — a movement whose list was never filled, or has been purged by retention", () => {
|
|
467
|
+
expect(fboFlightSchema.parse({ ...flightPayload, pobs: null }).pobs).toBeNull();
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
it("parses a stamped customs mail timestamp", () => {
|
|
471
|
+
const sent = { ...flightPayload, customs_mail_sent_at: "2026-08-28T09:15:00.000000Z" };
|
|
472
|
+
expect(fboFlightSchema.parse(sent).customs_mail_sent_at).toBe("2026-08-28T09:15:00.000000Z");
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it("rejects a POB entry missing its names inside an otherwise valid movement", () => {
|
|
476
|
+
const bad = { ...flightPayload, pobs: [{ crew: false, firstname: "Erika" }] };
|
|
477
|
+
expect(fboFlightSchema.safeParse(bad).success).toBe(false);
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Fixtures copied from `CompanyGrantResource`, the FBO meta endpoint and the
|
|
483
|
+
* attached-companies index, so a schema that drifts from the payload fails
|
|
484
|
+
* here rather than at runtime in the app.
|
|
485
|
+
*/
|
|
486
|
+
const grantPayload = {
|
|
487
|
+
id: 12,
|
|
488
|
+
grantee: { id: 34, name: "Alpha Handling" },
|
|
489
|
+
target: { id: 35, name: "Bravo Charter" },
|
|
490
|
+
ability: "duties.view",
|
|
491
|
+
ability_label: "Dienstpläne einsehen",
|
|
492
|
+
granted_by: { id: 7, name: "Erika Muster" },
|
|
493
|
+
created_at: "2026-08-29T09:00:00.000000Z",
|
|
494
|
+
can: { delete: true },
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
describe("fboCompanyGrantSchema", () => {
|
|
498
|
+
it("parses a grant exactly as the register emits it", () => {
|
|
499
|
+
expect(fboCompanyGrantSchema.parse(grantPayload).ability).toBe("duties.view");
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("parses a migrated grant nobody signed — granted_by is null", () => {
|
|
503
|
+
expect(fboCompanyGrantSchema.parse({ ...grantPayload, granted_by: null }).granted_by).toBeNull();
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it("parses a side whose company left the FBO domain — the ref is null, not missing", () => {
|
|
507
|
+
expect(fboCompanyGrantSchema.parse({ ...grantPayload, target: null }).target).toBeNull();
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("rejects an ability outside the register's vocabulary", () => {
|
|
511
|
+
expect(fboCompanyGrantSchema.safeParse({ ...grantPayload, ability: "flights.view" }).success).toBe(false);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("rejects a row without its ability label — the UI has no copy of its own", () => {
|
|
515
|
+
const { ability_label: _label, ...withoutLabel } = grantPayload;
|
|
516
|
+
expect(fboCompanyGrantSchema.safeParse(withoutLabel).success).toBe(false);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
describe("fboGrantAbilitySchema", () => {
|
|
521
|
+
it("accepts the one ability the register knows", () => {
|
|
522
|
+
expect(fboGrantAbilitySchema.parse("duties.view")).toBe("duties.view");
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it("rejects an ability the client cannot render", () => {
|
|
526
|
+
expect(fboGrantAbilitySchema.safeParse("traffic.details").success).toBe(false);
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
describe("fboMetaSchema", () => {
|
|
531
|
+
const metaPayload = {
|
|
532
|
+
roles: ["fbo", "operator"],
|
|
533
|
+
root_id: 34,
|
|
534
|
+
can_decide: true,
|
|
535
|
+
can_view_own_flights: false,
|
|
536
|
+
grant_abilities: [{ value: "duties.view", label: "View duty rosters" }],
|
|
537
|
+
can_manage_grants: true,
|
|
538
|
+
companies: [{ id: 34, name: "Alpha Handling" }],
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
it("parses the meta payload as the API emits it", () => {
|
|
542
|
+
const parsed = fboMetaSchema.parse(metaPayload);
|
|
543
|
+
expect(parsed.grant_abilities?.[0]?.value).toBe("duties.view");
|
|
544
|
+
expect(parsed.can_manage_grants).toBe(true);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it("parses a payload from an API that predates the grant register — only roles is required", () => {
|
|
548
|
+
const parsed = fboMetaSchema.parse({ roles: [] });
|
|
549
|
+
expect(parsed.grant_abilities).toBeUndefined();
|
|
550
|
+
expect(parsed.can_view_own_flights).toBeUndefined();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it("rejects a grant ability option the client cannot render", () => {
|
|
554
|
+
const bad = { ...metaPayload, grant_abilities: [{ value: "duties.edit", label: "Edit" }] };
|
|
555
|
+
expect(fboMetaSchema.safeParse(bad).success).toBe(false);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
describe("fboCompanySchema", () => {
|
|
560
|
+
const companyPayload = {
|
|
561
|
+
id: 35,
|
|
562
|
+
name: "Bravo Charter",
|
|
563
|
+
email: "ops@bravo.test",
|
|
564
|
+
phone: null,
|
|
565
|
+
description: null,
|
|
566
|
+
contact_name: "Erika Muster",
|
|
567
|
+
companyType: "interface",
|
|
568
|
+
is_ima_imported: true,
|
|
569
|
+
fbo: { role: "operator", flights_require_approval: true, notify_on_movement: false, has_duties: true, has_airplanes: false },
|
|
570
|
+
members_count: 4,
|
|
571
|
+
movements_count: 92,
|
|
572
|
+
grants_out_count: 1,
|
|
573
|
+
grants_in_count: 0,
|
|
574
|
+
can: { update: true, updateIdentity: true },
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
it("parses an attached company with both grant counts", () => {
|
|
578
|
+
const parsed = fboCompanySchema.parse(companyPayload);
|
|
579
|
+
expect(parsed.grants_out_count).toBe(1);
|
|
580
|
+
expect(parsed.grants_in_count).toBe(0);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it("parses a payload from an API that does not count grants yet", () => {
|
|
584
|
+
const { grants_out_count: _out, grants_in_count: _in, ...withoutCounts } = companyPayload;
|
|
585
|
+
expect(fboCompanySchema.parse(withoutCounts).grants_out_count).toBeUndefined();
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it("parses a company with no FBO profile at all", () => {
|
|
589
|
+
expect(fboCompanySchema.parse({ ...companyPayload, fbo: null }).fbo).toBeNull();
|
|
590
|
+
});
|
|
591
|
+
});
|
package/src/schemas/fbo.ts
CHANGED
|
@@ -64,6 +64,62 @@ export const fboRowCanSchema = z.object({
|
|
|
64
64
|
delete: z.boolean(),
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* One person on board a movement — the per-element shape of the flight's
|
|
69
|
+
* `pobs` list and, minus the row identity, of an address-book person.
|
|
70
|
+
* `birth`/`document_validity` are plain `Y-m-d` dates (no time); `nationality`
|
|
71
|
+
* is an uppercase ISO-3166-1 alpha-2 code. Every field but the names is
|
|
72
|
+
* optional data a filer may not have to hand yet.
|
|
73
|
+
*
|
|
74
|
+
* Passport data: it is only ever in a payload the API decided the caller may
|
|
75
|
+
* see (the movement's own author, or a root decider) — never cached to disk
|
|
76
|
+
* on the client.
|
|
77
|
+
*/
|
|
78
|
+
export const fboPobSchema = z.object({
|
|
79
|
+
/** Crew member rather than passenger — the customs declaration lists the two apart. */
|
|
80
|
+
crew: z.boolean(),
|
|
81
|
+
firstname: z.string(),
|
|
82
|
+
lastname: z.string(),
|
|
83
|
+
birth: z.string().nullable(),
|
|
84
|
+
nationality: z.string().nullable(),
|
|
85
|
+
document_id: z.string().nullable(),
|
|
86
|
+
document_validity: z.string().nullable(),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* An address-book person — a saved template the POB editor fills a row from,
|
|
91
|
+
* so a document number never has to be retyped. Same field set as
|
|
92
|
+
* `fboPobSchema` plus the row's own identity; `is_mine` says whether the
|
|
93
|
+
* CALLER owns it (theirs to edit or delete) rather than it merely being
|
|
94
|
+
* visible through the company they are filing at.
|
|
95
|
+
*/
|
|
96
|
+
export const fboPersonSchema = fboPobSchema.extend({
|
|
97
|
+
id: z.number(),
|
|
98
|
+
is_mine: z.boolean(),
|
|
99
|
+
created_at: z.string().nullable(),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A document hanging on a movement — General Declaration, passports, customs
|
|
104
|
+
* paperwork. `download_path` is a RELATIVE API path, never a fetchable file
|
|
105
|
+
* URL: the bytes live on a private disk and are streamed back through the
|
|
106
|
+
* authorised endpoint, so every fetch re-runs the caller's authority.
|
|
107
|
+
* `ima_file_id` is set only on the rows imported from the predecessor system,
|
|
108
|
+
* and is a STRING there — the importer stamps the source id as text.
|
|
109
|
+
*/
|
|
110
|
+
export const fboFlightDocumentSchema = z.object({
|
|
111
|
+
id: z.number(),
|
|
112
|
+
uuid: z.string().nullable(),
|
|
113
|
+
name: z.string(),
|
|
114
|
+
file_name: z.string(),
|
|
115
|
+
mime_type: z.string().nullable(),
|
|
116
|
+
size: z.number(),
|
|
117
|
+
collection_name: z.string(),
|
|
118
|
+
ima_file_id: z.string().nullable().optional(),
|
|
119
|
+
download_path: z.string().nullable(),
|
|
120
|
+
created_at: z.string().nullable(),
|
|
121
|
+
});
|
|
122
|
+
|
|
67
123
|
export const fboFlightSchema = z.object({
|
|
68
124
|
id: z.number(),
|
|
69
125
|
type: fboFlightTypeSchema,
|
|
@@ -104,6 +160,21 @@ export const fboFlightSchema = z.object({
|
|
|
104
160
|
batch_uuid: z.string().nullable(),
|
|
105
161
|
/** Count of live rows sharing `batch_uuid`; `1` when `batch_uuid` is null. */
|
|
106
162
|
legs_count: z.number(),
|
|
163
|
+
/**
|
|
164
|
+
* Persons on board. Own-row tier, stricter than `fbo_notes`: the key is
|
|
165
|
+
* present only for the movement's own AUTHOR or a root decider — a
|
|
166
|
+
* colleague reading the same row never receives it. `.optional()` covers
|
|
167
|
+
* the omitted key, `.nullable()` a movement whose list was never filled
|
|
168
|
+
* (or has been purged by retention).
|
|
169
|
+
*/
|
|
170
|
+
pobs: z.array(fboPobSchema).nullable().optional(),
|
|
171
|
+
/**
|
|
172
|
+
* How many documents hang on the movement. The files themselves are never
|
|
173
|
+
* listed here — they are fetched, and authorised, one endpoint deeper.
|
|
174
|
+
*/
|
|
175
|
+
documents_count: z.number().nullable().optional(),
|
|
176
|
+
/** When the customs pre-declaration was last mailed; `null` while it never was. */
|
|
177
|
+
customs_mail_sent_at: z.string().nullable().optional(),
|
|
107
178
|
/**
|
|
108
179
|
* Root tier — present only when the requesting user holds `fbo.flight.decide`
|
|
109
180
|
* for the row's company; absent (key omitted) for everyone else, including
|
|
@@ -365,3 +436,102 @@ export const fboMaterialiseResultSchema = z.object({
|
|
|
365
436
|
skipped_existing: z.number(),
|
|
366
437
|
skipped_closed: z.number(),
|
|
367
438
|
});
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* What one company may exercise on another company's data inside the same FBO
|
|
442
|
+
* tree — the vocabulary of the root's grant register. Mirrors the API enum
|
|
443
|
+
* exactly; a value outside it means the register grew an ability this client
|
|
444
|
+
* does not know how to render, and failing here is the point.
|
|
445
|
+
*/
|
|
446
|
+
export const fboGrantAbilitySchema = z.enum(["duties.view"]);
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* One entry of `GET fbo/meta`'s `grant_abilities` — the ability vocabulary
|
|
450
|
+
* with the label the API already translated, so no client hardcodes copy for
|
|
451
|
+
* an ability it may not know.
|
|
452
|
+
*/
|
|
453
|
+
export const fboGrantAbilityOptionSchema = z.object({
|
|
454
|
+
value: fboGrantAbilitySchema,
|
|
455
|
+
label: z.string(),
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* A company side of a grant. Rendered as `{id, name}` rather than a full
|
|
460
|
+
* company payload: a grant is a relation between two companies, not a view of
|
|
461
|
+
* either. Null only when that company stopped taking part in the FBO domain.
|
|
462
|
+
*/
|
|
463
|
+
export const fboGrantCompanyRefSchema = z.object({
|
|
464
|
+
id: z.number(),
|
|
465
|
+
name: z.string().nullable(),
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* One row of the root's company-grant register — `CompanyGrantResource`.
|
|
470
|
+
* `granted_by` is null for a grant the migration wrote rather than a person.
|
|
471
|
+
* `can.delete` is always true on a row that reached the client at all (only
|
|
472
|
+
* `fbo.company.manage` at the tree root can read the register), but it is
|
|
473
|
+
* read as a gate like every other row's, never assumed.
|
|
474
|
+
*/
|
|
475
|
+
export const fboCompanyGrantSchema = z.object({
|
|
476
|
+
id: z.number(),
|
|
477
|
+
grantee: fboGrantCompanyRefSchema.nullable(),
|
|
478
|
+
target: fboGrantCompanyRefSchema.nullable(),
|
|
479
|
+
ability: fboGrantAbilitySchema,
|
|
480
|
+
ability_label: z.string(),
|
|
481
|
+
granted_by: z.object({ id: z.number(), name: z.string() }).nullable(),
|
|
482
|
+
created_at: z.string().nullable(),
|
|
483
|
+
can: z.object({ delete: z.boolean() }).optional(),
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
/** `POST companies/{id}/fbo/company-grants` — the register's write shape. */
|
|
487
|
+
export const fboCompanyGrantInputSchema = z.object({
|
|
488
|
+
grantee_company_id: z.number(),
|
|
489
|
+
target_company_id: z.number(),
|
|
490
|
+
ability: fboGrantAbilitySchema,
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* `GET companies/{id}/fbo/meta` — the FBO vocabulary and the caller's
|
|
495
|
+
* root-evaluated capabilities, served so no client hardcodes either.
|
|
496
|
+
*
|
|
497
|
+
* Every key but `roles` is optional: the endpoint is the one surface an
|
|
498
|
+
* own-author filer can reach before anything else is known, and it has grown
|
|
499
|
+
* keys over time — a client pinned to an older API must still parse it.
|
|
500
|
+
*
|
|
501
|
+
* `can_view_own_flights` is the TIER, not the bare permission: true only when
|
|
502
|
+
* this caller's sight of movements is the own-author one (false for a decider
|
|
503
|
+
* or an operator, who hold the wider `fbo.flight.viewAny`).
|
|
504
|
+
*/
|
|
505
|
+
export const fboMetaSchema = z.object({
|
|
506
|
+
roles: z.array(z.string()),
|
|
507
|
+
root_id: z.number().nullable().optional(),
|
|
508
|
+
can_decide: z.boolean().optional(),
|
|
509
|
+
can_view_own_flights: z.boolean().optional(),
|
|
510
|
+
grant_abilities: z.array(fboGrantAbilityOptionSchema).optional(),
|
|
511
|
+
can_manage_grants: z.boolean().optional(),
|
|
512
|
+
companies: z.array(fboGrantCompanyRefSchema).optional(),
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* A company attached to the FBO as its root's admin reads it —
|
|
517
|
+
* `CompanyResource` under `GET companies/{fbo}/fbo/companies`. The three
|
|
518
|
+
* counts are aggregates the index adds (`withCount`) and are null on any
|
|
519
|
+
* payload that did not compute them; `grants_out_count`/`grants_in_count`
|
|
520
|
+
* are additionally optional, being newer than the surface itself.
|
|
521
|
+
*/
|
|
522
|
+
export const fboCompanySchema = z.object({
|
|
523
|
+
id: z.number(),
|
|
524
|
+
name: z.string(),
|
|
525
|
+
email: z.string().nullable(),
|
|
526
|
+
phone: z.string().nullable(),
|
|
527
|
+
description: z.string().nullable(),
|
|
528
|
+
contact_name: z.string().nullable(),
|
|
529
|
+
companyType: z.string(),
|
|
530
|
+
is_ima_imported: z.boolean(),
|
|
531
|
+
fbo: fboCompanyProfileSchema.nullable(),
|
|
532
|
+
members_count: z.number().nullable(),
|
|
533
|
+
movements_count: z.number().nullable(),
|
|
534
|
+
grants_out_count: z.number().nullable().optional(),
|
|
535
|
+
grants_in_count: z.number().nullable().optional(),
|
|
536
|
+
can: z.object({ update: z.boolean(), updateIdentity: z.boolean() }),
|
|
537
|
+
});
|
package/src/types/fbo.ts
CHANGED
|
@@ -7,6 +7,9 @@ export type FboGroundServices = z.infer<typeof Fbo.fboGroundServicesSchema>;
|
|
|
7
7
|
export type FboFlightType = z.infer<typeof Fbo.fboFlightTypeSchema>;
|
|
8
8
|
export type FboFlightStatus = z.infer<typeof Fbo.fboFlightStatusSchema>;
|
|
9
9
|
export type FboOperations = z.infer<typeof Fbo.fboOperationsSchema>;
|
|
10
|
+
export type FboPob = z.infer<typeof Fbo.fboPobSchema>;
|
|
11
|
+
export type FboPerson = z.infer<typeof Fbo.fboPersonSchema>;
|
|
12
|
+
export type FboFlightDocument = z.infer<typeof Fbo.fboFlightDocumentSchema>;
|
|
10
13
|
export type FboFlight = z.infer<typeof Fbo.fboFlightSchema>;
|
|
11
14
|
export type FboOccupation = z.infer<typeof Fbo.fboOccupationSchema>;
|
|
12
15
|
export type FboDuty = z.infer<typeof Fbo.fboDutySchema>;
|
|
@@ -33,3 +36,10 @@ export type FboActivityChanges = z.infer<typeof Fbo.fboActivityChangesSchema>;
|
|
|
33
36
|
export type FboActivity = z.infer<typeof Fbo.fboActivitySchema>;
|
|
34
37
|
export type FboRecurringFlight = z.infer<typeof Fbo.fboRecurringFlightSchema>;
|
|
35
38
|
export type FboMaterialiseResult = z.infer<typeof Fbo.fboMaterialiseResultSchema>;
|
|
39
|
+
export type FboGrantAbility = z.infer<typeof Fbo.fboGrantAbilitySchema>;
|
|
40
|
+
export type FboGrantAbilityOption = z.infer<typeof Fbo.fboGrantAbilityOptionSchema>;
|
|
41
|
+
export type FboGrantCompanyRef = z.infer<typeof Fbo.fboGrantCompanyRefSchema>;
|
|
42
|
+
export type FboCompanyGrant = z.infer<typeof Fbo.fboCompanyGrantSchema>;
|
|
43
|
+
export type FboCompanyGrantInput = z.infer<typeof Fbo.fboCompanyGrantInputSchema>;
|
|
44
|
+
export type FboMeta = z.infer<typeof Fbo.fboMetaSchema>;
|
|
45
|
+
export type FboCompany = z.infer<typeof Fbo.fboCompanySchema>;
|