@aeolus-fleet/core 0.18.0 → 0.20.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.
- package/LICENSE +201 -0
- package/dist/adapters/prisma/generated/browser.d.ts +25 -0
- package/dist/adapters/prisma/generated/client.d.ts +25 -0
- package/dist/adapters/prisma/generated/internal/class.d.ts +44 -0
- package/dist/adapters/prisma/generated/internal/class.js +4 -4
- package/dist/adapters/prisma/generated/internal/class.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +338 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js +34 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +37 -0
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +34 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
- package/dist/adapters/prisma/generated/models/CrewRequest.d.ts +103 -1
- package/dist/adapters/prisma/generated/models/Fleet.d.ts +860 -0
- package/dist/adapters/prisma/generated/models/Label.d.ts +1475 -0
- package/dist/adapters/prisma/generated/models/Label.js +2 -0
- package/dist/adapters/prisma/generated/models/Label.js.map +1 -0
- package/dist/adapters/prisma/generated/models/LabelValue.d.ts +1454 -0
- package/dist/adapters/prisma/generated/models/LabelValue.js +2 -0
- package/dist/adapters/prisma/generated/models/LabelValue.js.map +1 -0
- package/dist/adapters/prisma/generated/models/Ship.d.ts +1225 -70
- package/dist/adapters/prisma/generated/models/ShipLabel.d.ts +1431 -0
- package/dist/adapters/prisma/generated/models/ShipLabel.js +2 -0
- package/dist/adapters/prisma/generated/models/ShipLabel.js.map +1 -0
- package/dist/adapters/prisma/generated/models/WorktreeClearRequest.d.ts +1539 -0
- package/dist/adapters/prisma/generated/models/WorktreeClearRequest.js +2 -0
- package/dist/adapters/prisma/generated/models/WorktreeClearRequest.js.map +1 -0
- package/dist/adapters/prisma/generated/models.d.ts +4 -0
- package/dist/adapters/prisma/registry.d.ts +3 -1
- package/dist/adapters/prisma/registry.js +129 -9
- package/dist/adapters/prisma/registry.js.map +1 -1
- package/dist/adapters/prisma/rows.d.ts +10 -0
- package/dist/adapters/prisma/rows.js +41 -2
- package/dist/adapters/prisma/rows.js.map +1 -1
- package/dist/adapters/prisma/unit-of-work.d.ts +3 -1
- package/dist/adapters/prisma/unit-of-work.js +3 -1
- package/dist/adapters/prisma/unit-of-work.js.map +1 -1
- package/dist/adapters/trpc/console.d.ts +1 -1
- package/dist/adapters/trpc/context.d.ts +20 -0
- package/dist/adapters/trpc/fleet.d.ts +144 -8
- package/dist/adapters/trpc/fleet.js +149 -12
- package/dist/adapters/trpc/fleet.js.map +1 -1
- package/dist/adapters/trpc/router.d.ts +134 -8
- package/dist/adapters/trpc/ship-contract.js +10 -0
- package/dist/adapters/trpc/ship-contract.js.map +1 -1
- package/dist/adapters/trpc/trpc.d.ts +2 -2
- package/dist/adapters/trpc/trpc.js +16 -2
- package/dist/adapters/trpc/trpc.js.map +1 -1
- package/dist/domain/registry/assign-label.d.ts +32 -0
- package/dist/domain/registry/assign-label.js +39 -0
- package/dist/domain/registry/assign-label.js.map +1 -0
- package/dist/domain/registry/change-label-values.d.ts +33 -0
- package/dist/domain/registry/change-label-values.js +34 -0
- package/dist/domain/registry/change-label-values.js.map +1 -0
- package/dist/domain/registry/clear-request.d.ts +69 -0
- package/dist/domain/registry/clear-request.js +51 -0
- package/dist/domain/registry/clear-request.js.map +1 -0
- package/dist/domain/registry/confirm-worktree-cleared.d.ts +31 -0
- package/dist/domain/registry/confirm-worktree-cleared.js +30 -0
- package/dist/domain/registry/confirm-worktree-cleared.js.map +1 -0
- package/dist/domain/registry/crew-request.d.ts +9 -3
- package/dist/domain/registry/crew-request.js +9 -6
- package/dist/domain/registry/crew-request.js.map +1 -1
- package/dist/domain/registry/define-label.d.ts +33 -0
- package/dist/domain/registry/define-label.js +33 -0
- package/dist/domain/registry/define-label.js.map +1 -0
- package/dist/domain/registry/delete-label.d.ts +30 -0
- package/dist/domain/registry/delete-label.js +32 -0
- package/dist/domain/registry/delete-label.js.map +1 -0
- package/dist/domain/registry/find-label-value.d.ts +22 -0
- package/dist/domain/registry/find-label-value.js +19 -0
- package/dist/domain/registry/find-label-value.js.map +1 -0
- package/dist/domain/registry/get-ship.d.ts +1 -1
- package/dist/domain/registry/get-ship.js +2 -2
- package/dist/domain/registry/get-ship.js.map +1 -1
- package/dist/domain/registry/get-starting-prompt.js +3 -3
- package/dist/domain/registry/get-starting-prompt.js.map +1 -1
- package/dist/domain/registry/label.d.ts +197 -0
- package/dist/domain/registry/label.js +263 -0
- package/dist/domain/registry/label.js.map +1 -0
- package/dist/domain/registry/list-fleet.d.ts +13 -7
- package/dist/domain/registry/list-fleet.js +10 -5
- package/dist/domain/registry/list-fleet.js.map +1 -1
- package/dist/domain/registry/list-labels.d.ts +12 -0
- package/dist/domain/registry/list-labels.js +9 -0
- package/dist/domain/registry/list-labels.js.map +1 -0
- package/dist/domain/registry/ports.d.ts +59 -1
- package/dist/domain/registry/read-clear-requests.d.ts +15 -0
- package/dist/domain/registry/read-clear-requests.js +16 -0
- package/dist/domain/registry/read-clear-requests.js.map +1 -0
- package/dist/domain/registry/release-ship.d.ts +1 -1
- package/dist/domain/registry/release-ship.js +2 -2
- package/dist/domain/registry/release-ship.js.map +1 -1
- package/dist/domain/registry/report-crew-status.d.ts +6 -3
- package/dist/domain/registry/report-crew-status.js +11 -4
- package/dist/domain/registry/report-crew-status.js.map +1 -1
- package/dist/domain/registry/request-worktree-clear.d.ts +31 -0
- package/dist/domain/registry/request-worktree-clear.js +35 -0
- package/dist/domain/registry/request-worktree-clear.js.map +1 -0
- package/dist/domain/registry/retire-ship.d.ts +9 -3
- package/dist/domain/registry/retire-ship.js +27 -2
- package/dist/domain/registry/retire-ship.js.map +1 -1
- package/dist/domain/registry/ship.d.ts +1 -1
- package/dist/domain/registry/unassign-label.d.ts +30 -0
- package/dist/domain/registry/unassign-label.js +37 -0
- package/dist/domain/registry/unassign-label.js.map +1 -0
- package/dist/domain/shared/errors.d.ts +1 -1
- package/dist/domain/shared/errors.js.map +1 -1
- package/dist/wiring.d.ts +20 -0
- package/dist/wiring.js +21 -1
- package/dist/wiring.js.map +1 -1
- package/package.json +7 -5
- package/src/adapters/prisma/migrations/20261007020000_broad_crewing_scope_retired/migration.sql +8 -0
- package/src/adapters/prisma/migrations/20261007100000_labels/migration.sql +87 -0
- package/src/adapters/prisma/migrations/20261007110000_foreign_key_indexes/migration.sql +42 -0
- package/src/adapters/prisma/migrations/20261007120000_crew_status_attempt/migration.sql +4 -0
- package/src/adapters/prisma/migrations/20261007140000_worktree_clear_requests/migration.sql +32 -0
- package/src/adapters/prisma/schema.prisma +120 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CLEAR_REQUESTS_PER_TRIERARCH_MAX } from '@aeolus-fleet/common';
|
|
2
|
+
import { refuse } from '../shared/errors.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
/** The type of the ship a trierarch crews (docs/trierarch.md). */
|
|
5
|
+
export const TRIERARCH_SHIP_TYPE = 'trierarch';
|
|
6
|
+
function event(trierarch, change) {
|
|
7
|
+
const { at, actor, ...what } = change;
|
|
8
|
+
return { fleetId: trierarch.fleetId, occurredAt: at, actor, shipId: trierarch.id, ...what };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A ship asks a trierarch to clear the worktree it kept for a ship in a
|
|
12
|
+
* repository: the request, and WorktreeClearRequested on the trierarch's
|
|
13
|
+
* ship. Only a trierarch that is not retired; at most
|
|
14
|
+
* CLEAR_REQUESTS_PER_TRIERARCH_MAX pending at once. A request it holds
|
|
15
|
+
* already changes nothing: no request and no event.
|
|
16
|
+
*/
|
|
17
|
+
export function requestWorktreeClear({ trierarch, current, pending }, input) {
|
|
18
|
+
if (trierarch.type !== TRIERARCH_SHIP_TYPE) {
|
|
19
|
+
return refuse('NOT_A_TRIERARCH', `${trierarch.name} is no trierarch: only a trierarch clears a worktree it kept`);
|
|
20
|
+
}
|
|
21
|
+
if (trierarch.retiredAt !== null) {
|
|
22
|
+
return refuse('SHIP_ALREADY_RETIRED', `${trierarch.name} is retired: a retired trierarch clears nothing`);
|
|
23
|
+
}
|
|
24
|
+
if (current) {
|
|
25
|
+
return ok({ request: null, events: [] });
|
|
26
|
+
}
|
|
27
|
+
if (pending >= CLEAR_REQUESTS_PER_TRIERARCH_MAX) {
|
|
28
|
+
return refuse('CLEAR_REQUEST_LIMIT_REACHED', `${trierarch.name} holds ${String(CLEAR_REQUESTS_PER_TRIERARCH_MAX)} clear requests already, the most a trierarch may hold (decision 0032): ask again once it confirms some`);
|
|
29
|
+
}
|
|
30
|
+
const { shipId, repository, requestedBy, at, actor } = input;
|
|
31
|
+
return ok({
|
|
32
|
+
request: { fleetId: trierarch.fleetId, trierarchShipId: trierarch.id, shipId, repository, requestedBy, requestedAt: at },
|
|
33
|
+
events: [event(trierarch, { type: 'WorktreeClearRequested', details: { worktreeShipId: shipId, repository }, at, actor })],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The trierarch confirms a clear request it holds, saying how it came out:
|
|
38
|
+
* the request goes, with WorktreeCleared and the outcome.
|
|
39
|
+
*/
|
|
40
|
+
export function confirmWorktreeCleared({ trierarch, worktreeShipName, current }, input) {
|
|
41
|
+
const { repository, outcome, at, actor } = input;
|
|
42
|
+
if (!current) {
|
|
43
|
+
return refuse('CLEAR_REQUEST_NOT_FOUND', `${trierarch.name} holds no clear request for the ${repository} worktree of ${worktreeShipName}`);
|
|
44
|
+
}
|
|
45
|
+
return ok({ events: [event(trierarch, { type: 'WorktreeCleared', details: { worktreeShipId: current.shipId, repository, outcome }, at, actor })] });
|
|
46
|
+
}
|
|
47
|
+
/** A retired trierarch clears nothing: its pending requests go, one WorktreeClearRemoved each. */
|
|
48
|
+
export function removeClearRequestsOf({ trierarch, requests }, change) {
|
|
49
|
+
return requests.map(({ shipId, repository }) => event(trierarch, { type: 'WorktreeClearRemoved', details: { worktreeShipId: shipId, repository }, ...change }));
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=clear-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-request.js","sourceRoot":"","sources":["../../../src/domain/registry/clear-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ClearOutcome, IdGenerator, ShipId } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type DomainError } from '../shared/errors.js';
|
|
5
|
+
import { type EventLog } from '../shared/events.js';
|
|
6
|
+
import { type Result } from '../shared/result.js';
|
|
7
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
8
|
+
import { type ConfirmWorktreeClearedRefusal } from './clear-request.js';
|
|
9
|
+
import type { ClearRequestRepository, ShipRepository } from './ports.js';
|
|
10
|
+
export interface ConfirmWorktreeClearedTx {
|
|
11
|
+
ships: Pick<ShipRepository, 'find' | 'findForUpdate'>;
|
|
12
|
+
clearRequests: ClearRequestRepository;
|
|
13
|
+
events: EventLog;
|
|
14
|
+
}
|
|
15
|
+
export type ConfirmWorktreeClearedUseCaseRefusal = DomainError<'SHIP_NOT_FOUND'> | ConfirmWorktreeClearedRefusal;
|
|
16
|
+
export type ConfirmWorktreeCleared = (caller: Caller, input: {
|
|
17
|
+
shipId: ShipId;
|
|
18
|
+
repository: string;
|
|
19
|
+
outcome: ClearOutcome;
|
|
20
|
+
}) => Promise<Result<undefined, ConfirmWorktreeClearedUseCaseRefusal>>;
|
|
21
|
+
/**
|
|
22
|
+
* Use case: a trierarch confirms a clear request to its own ship, saying it
|
|
23
|
+
* removed the worktree or kept none (decision 0032). Its scope (crew:run) is
|
|
24
|
+
* checked before this runs. In one unit of work, locking its ship first: the
|
|
25
|
+
* request goes, with WorktreeCleared.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createConfirmWorktreeCleared(deps: {
|
|
28
|
+
uow: UnitOfWork<ConfirmWorktreeClearedTx>;
|
|
29
|
+
clock: Clock;
|
|
30
|
+
ids: IdGenerator;
|
|
31
|
+
}): ConfirmWorktreeCleared;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { recordEvent, shipActor } from '../shared/events.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
import { confirmWorktreeCleared } from './clear-request.js';
|
|
5
|
+
/**
|
|
6
|
+
* Use case: a trierarch confirms a clear request to its own ship, saying it
|
|
7
|
+
* removed the worktree or kept none (decision 0032). Its scope (crew:run) is
|
|
8
|
+
* checked before this runs. In one unit of work, locking its ship first: the
|
|
9
|
+
* request goes, with WorktreeCleared.
|
|
10
|
+
*/
|
|
11
|
+
export function createConfirmWorktreeCleared(deps) {
|
|
12
|
+
return (caller, input) => deps.uow.run(async (tx) => {
|
|
13
|
+
const { fleetId } = caller;
|
|
14
|
+
const trierarch = await tx.ships.findForUpdate(fleetId, caller.shipId);
|
|
15
|
+
if (!trierarch) {
|
|
16
|
+
return refuse('SHIP_NOT_FOUND', `Ship ${caller.shipId} does not exist`);
|
|
17
|
+
}
|
|
18
|
+
const key = { trierarchShipId: trierarch.id, shipId: input.shipId, repository: input.repository };
|
|
19
|
+
const confirmed = confirmWorktreeCleared({ trierarch, worktreeShipName: (await tx.ships.find(fleetId, input.shipId))?.name ?? input.shipId, current: await tx.clearRequests.find(fleetId, key) }, { repository: input.repository, outcome: input.outcome, at: deps.clock.now(), actor: shipActor(caller.shipId) });
|
|
20
|
+
if (!confirmed.isOk) {
|
|
21
|
+
return confirmed;
|
|
22
|
+
}
|
|
23
|
+
await tx.clearRequests.remove(fleetId, key);
|
|
24
|
+
for (const event of confirmed.value.events) {
|
|
25
|
+
await recordEvent({ events: tx.events, ids: deps.ids }, event);
|
|
26
|
+
}
|
|
27
|
+
return ok(undefined);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=confirm-worktree-cleared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-worktree-cleared.js","sourceRoot":"","sources":["../../../src/domain/registry/confirm-worktree-cleared.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAsC,MAAM,oBAAoB,CAAC;AAgBhG;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAAmF;IAC9H,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAoE,EAAE;QAC1F,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,MAAM,CAAC,gBAAgB,EAAE,QAAQ,MAAM,CAAC,MAAM,iBAAiB,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,GAAG,GAAG,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QAClG,MAAM,SAAS,GAAG,sBAAsB,CACtC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EACvJ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAChH,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC5C,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3C,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -28,6 +28,10 @@ export interface CrewRequest {
|
|
|
28
28
|
status: CrewStatus | null;
|
|
29
29
|
/** Why no trierarch can take it, written by the assigner while unassigned; null when none. */
|
|
30
30
|
reason: string | null;
|
|
31
|
+
/** How many times its trierarch restarted the session within its restart window, written with the status: 0 on its first start (#332). */
|
|
32
|
+
attempt: number;
|
|
33
|
+
/** When the session its trierarch runs now started, written with the status; null while none runs. */
|
|
34
|
+
sessionStartedAt: Date | null;
|
|
31
35
|
}
|
|
32
36
|
type NotFound = DomainError<'CREW_REQUEST_NOT_FOUND'>;
|
|
33
37
|
type Releasing = DomainError<'CREW_REQUEST_RELEASING'>;
|
|
@@ -105,9 +109,9 @@ export declare function explainCrewRequest({ ship, current }: {
|
|
|
105
109
|
events: NewEvent[];
|
|
106
110
|
}, ExplainCrewRequestRefusal>;
|
|
107
111
|
/**
|
|
108
|
-
* The assigned trierarch writes how its crew of the ship stands, with
|
|
109
|
-
*
|
|
110
|
-
* releasing.
|
|
112
|
+
* The assigned trierarch writes how its crew of the ship stands, with the
|
|
113
|
+
* restart attempt and when the session started (#332), and CrewStatusChanged
|
|
114
|
+
* when any of them changes. Once the request is releasing, only releasing.
|
|
111
115
|
*/
|
|
112
116
|
export declare function reportCrewStatus({ ship, current, trierarchShipId }: {
|
|
113
117
|
ship: Ship;
|
|
@@ -115,6 +119,8 @@ export declare function reportCrewStatus({ ship, current, trierarchShipId }: {
|
|
|
115
119
|
trierarchShipId: ShipId;
|
|
116
120
|
}, input: {
|
|
117
121
|
status: CrewStatus;
|
|
122
|
+
attempt: number;
|
|
123
|
+
sessionStartedAt: Date | null;
|
|
118
124
|
at: Date;
|
|
119
125
|
actor: Actor;
|
|
120
126
|
}): Result<{
|
|
@@ -38,6 +38,8 @@ export function requestCrew({ ship, current }, input) {
|
|
|
38
38
|
assignedTo: current?.assignedTo ?? null,
|
|
39
39
|
status: current?.status ?? null,
|
|
40
40
|
reason: current?.reason ?? null,
|
|
41
|
+
attempt: current?.attempt ?? 0,
|
|
42
|
+
sessionStartedAt: current?.sessionStartedAt ?? null,
|
|
41
43
|
};
|
|
42
44
|
return ok({ request, events: [event(ship, { at: input.at, actor: input.actor, type: 'CrewRequested', details: { settingsVersion: request.settingsVersion } })] });
|
|
43
45
|
}
|
|
@@ -119,9 +121,9 @@ function checkAssignedTo({ ship, current, trierarchShipId }) {
|
|
|
119
121
|
: refuse('CREW_REQUEST_NOT_ASSIGNED_TO_CALLER', `${ship.name}'s crew request is not assigned to your ship`);
|
|
120
122
|
}
|
|
121
123
|
/**
|
|
122
|
-
* The assigned trierarch writes how its crew of the ship stands, with
|
|
123
|
-
*
|
|
124
|
-
* releasing.
|
|
124
|
+
* The assigned trierarch writes how its crew of the ship stands, with the
|
|
125
|
+
* restart attempt and when the session started (#332), and CrewStatusChanged
|
|
126
|
+
* when any of them changes. Once the request is releasing, only releasing.
|
|
125
127
|
*/
|
|
126
128
|
export function reportCrewStatus({ ship, current, trierarchShipId }, input) {
|
|
127
129
|
if (!current) {
|
|
@@ -134,12 +136,13 @@ export function reportCrewStatus({ ship, current, trierarchShipId }, input) {
|
|
|
134
136
|
if (current.status === 'releasing' && input.status !== 'releasing') {
|
|
135
137
|
return refuse('CREW_REQUEST_RELEASING', `${ship.name}'s crew request is releasing: stop its session, end its lease and confirm`);
|
|
136
138
|
}
|
|
137
|
-
|
|
139
|
+
const isSameStart = (current.sessionStartedAt?.getTime() ?? null) === (input.sessionStartedAt?.getTime() ?? null);
|
|
140
|
+
if (current.status === input.status && current.attempt === input.attempt && isSameStart) {
|
|
138
141
|
return ok({ request: current, events: [] });
|
|
139
142
|
}
|
|
140
143
|
return ok({
|
|
141
|
-
request: { ...current, status: input.status },
|
|
142
|
-
events: [event(ship, { at: input.at, actor: input.actor, type: 'CrewStatusChanged', details: { status: input.status } })],
|
|
144
|
+
request: { ...current, status: input.status, attempt: input.attempt, sessionStartedAt: input.sessionStartedAt },
|
|
145
|
+
events: [event(ship, { at: input.at, actor: input.actor, type: 'CrewStatusChanged', details: { status: input.status, attempt: input.attempt } })],
|
|
143
146
|
});
|
|
144
147
|
}
|
|
145
148
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crew-request.js","sourceRoot":"","sources":["../../../src/domain/registry/crew-request.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,+BAA+B,EAC/B,SAAS,EACT,wBAAwB,GAKzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAe,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,uBAAuB,EAA0C,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"crew-request.js","sourceRoot":"","sources":["../../../src/domain/registry/crew-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IdGenerator, LabelId } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type EventLog } from '../shared/events.js';
|
|
5
|
+
import { type Result } from '../shared/result.js';
|
|
6
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
7
|
+
import { type DefineLabelRefusal, type LabelValue } from './label.js';
|
|
8
|
+
import type { LabelRepository, ShipRepository } from './ports.js';
|
|
9
|
+
export interface DefineLabelTx {
|
|
10
|
+
ships: Pick<ShipRepository, 'find'>;
|
|
11
|
+
labels: Pick<LabelRepository, 'lockKey' | 'findByKey' | 'save'>;
|
|
12
|
+
events: EventLog;
|
|
13
|
+
}
|
|
14
|
+
/** The new label's id, and its values with their ids. */
|
|
15
|
+
export interface DefinedLabel {
|
|
16
|
+
labelId: LabelId;
|
|
17
|
+
values: readonly LabelValue[];
|
|
18
|
+
}
|
|
19
|
+
export type DefineLabel = (caller: Caller, input: {
|
|
20
|
+
key: string;
|
|
21
|
+
values: readonly string[];
|
|
22
|
+
}) => Promise<Result<DefinedLabel, DefineLabelRefusal>>;
|
|
23
|
+
/**
|
|
24
|
+
* Use case: the caller's ship defines a label it then owns (decision 0031).
|
|
25
|
+
* Its scope (labels:define) is checked before this runs. In one unit of work,
|
|
26
|
+
* holding the key's lock so two definitions of one key never both find it
|
|
27
|
+
* free: the label, a new id for it and each of its values, and LabelDefined.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createDefineLabel(deps: {
|
|
30
|
+
uow: UnitOfWork<DefineLabelTx>;
|
|
31
|
+
clock: Clock;
|
|
32
|
+
ids: IdGenerator;
|
|
33
|
+
}): DefineLabel;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { recordEvent, shipActor } from '../shared/events.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
import { defineLabel } from './label.js';
|
|
4
|
+
/**
|
|
5
|
+
* Use case: the caller's ship defines a label it then owns (decision 0031).
|
|
6
|
+
* Its scope (labels:define) is checked before this runs. In one unit of work,
|
|
7
|
+
* holding the key's lock so two definitions of one key never both find it
|
|
8
|
+
* free: the label, a new id for it and each of its values, and LabelDefined.
|
|
9
|
+
*/
|
|
10
|
+
export function createDefineLabel(deps) {
|
|
11
|
+
return (caller, input) => deps.uow.run(async (tx) => {
|
|
12
|
+
const { fleetId } = caller;
|
|
13
|
+
await tx.labels.lockKey(fleetId, input.key);
|
|
14
|
+
const label = await tx.labels.findByKey(fleetId, input.key);
|
|
15
|
+
const owner = label && (await tx.ships.find(fleetId, label.ownerShipId));
|
|
16
|
+
const defined = defineLabel({ owner: { fleetId, id: caller.shipId }, existing: label && { label, ownerName: owner?.name ?? label.ownerShipId } }, {
|
|
17
|
+
id: deps.ids('label'),
|
|
18
|
+
key: input.key,
|
|
19
|
+
values: input.values.map((value) => ({ value, newId: deps.ids('labelValue') })),
|
|
20
|
+
at: deps.clock.now(),
|
|
21
|
+
actor: shipActor(caller.shipId),
|
|
22
|
+
});
|
|
23
|
+
if (!defined.isOk) {
|
|
24
|
+
return defined;
|
|
25
|
+
}
|
|
26
|
+
await tx.labels.save(defined.value.label);
|
|
27
|
+
for (const event of defined.value.events) {
|
|
28
|
+
await recordEvent({ events: tx.events, ids: deps.ids }, event);
|
|
29
|
+
}
|
|
30
|
+
return ok({ labelId: defined.value.label.id, values: defined.value.label.values });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=define-label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-label.js","sourceRoot":"","sources":["../../../src/domain/registry/define-label.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAA4C,MAAM,YAAY,CAAC;AAiBnF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwE;IACxG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAqD,EAAE;QAC3E,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,WAAW,CACzB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,EACpH;YACE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YACrB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC/E,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;SAChC,CACF,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IdGenerator, LabelId } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type DomainError } from '../shared/errors.js';
|
|
5
|
+
import { type EventLog } from '../shared/events.js';
|
|
6
|
+
import { type Result } from '../shared/result.js';
|
|
7
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
8
|
+
import { type DeleteLabelRefusal } from './label.js';
|
|
9
|
+
import type { LabelRepository, ShipRepository } from './ports.js';
|
|
10
|
+
export interface DeleteLabelTx {
|
|
11
|
+
ships: Pick<ShipRepository, 'find'>;
|
|
12
|
+
labels: Pick<LabelRepository, 'findForUpdate' | 'carriersOf' | 'remove'>;
|
|
13
|
+
events: EventLog;
|
|
14
|
+
}
|
|
15
|
+
export type DeleteLabelFailure = DomainError<'LABEL_NOT_FOUND'> | DeleteLabelRefusal;
|
|
16
|
+
export type DeleteLabel = (caller: Caller, input: {
|
|
17
|
+
labelId: LabelId;
|
|
18
|
+
}) => Promise<Result<undefined, DeleteLabelFailure>>;
|
|
19
|
+
/**
|
|
20
|
+
* Use case: a label's owner deletes it, freeing its key (decision 0031). Its
|
|
21
|
+
* scope (labels:define) is checked before this runs. In one unit of work,
|
|
22
|
+
* locking the label first, as a change of values does, so an assignment
|
|
23
|
+
* either comes before and is seen here, or waits and finds the label gone:
|
|
24
|
+
* the label goes with its values, with LabelDeleted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createDeleteLabel(deps: {
|
|
27
|
+
uow: UnitOfWork<DeleteLabelTx>;
|
|
28
|
+
clock: Clock;
|
|
29
|
+
ids: IdGenerator;
|
|
30
|
+
}): DeleteLabel;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { recordEvent, shipActor } from '../shared/events.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
import { deleteLabel } from './label.js';
|
|
5
|
+
/**
|
|
6
|
+
* Use case: a label's owner deletes it, freeing its key (decision 0031). Its
|
|
7
|
+
* scope (labels:define) is checked before this runs. In one unit of work,
|
|
8
|
+
* locking the label first, as a change of values does, so an assignment
|
|
9
|
+
* either comes before and is seen here, or waits and finds the label gone:
|
|
10
|
+
* the label goes with its values, with LabelDeleted.
|
|
11
|
+
*/
|
|
12
|
+
export function createDeleteLabel(deps) {
|
|
13
|
+
return (caller, input) => deps.uow.run(async (tx) => {
|
|
14
|
+
const { fleetId } = caller;
|
|
15
|
+
const label = await tx.labels.findForUpdate(fleetId, input.labelId);
|
|
16
|
+
if (!label) {
|
|
17
|
+
return refuse('LABEL_NOT_FOUND', `The fleet has no label ${input.labelId}`);
|
|
18
|
+
}
|
|
19
|
+
const nameOf = async (shipId) => (await tx.ships.find(fleetId, shipId))?.name ?? shipId;
|
|
20
|
+
const carrierNames = await Promise.all((await tx.labels.carriersOf(fleetId, label.id)).map((carried) => nameOf(carried.shipId)));
|
|
21
|
+
const deleted = deleteLabel({ label, ownerName: await nameOf(label.ownerShipId), carrierNames }, { callerShipId: caller.shipId, at: deps.clock.now(), actor: shipActor(caller.shipId) });
|
|
22
|
+
if (!deleted.isOk) {
|
|
23
|
+
return deleted;
|
|
24
|
+
}
|
|
25
|
+
await tx.labels.remove(fleetId, label.id);
|
|
26
|
+
for (const event of deleted.value.events) {
|
|
27
|
+
await recordEvent({ events: tx.events, ids: deps.ids }, event);
|
|
28
|
+
}
|
|
29
|
+
return ok(undefined);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=delete-label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete-label.js","sourceRoot":"","sources":["../../../src/domain/registry/delete-label.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAalE;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwE;IACxG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAkD,EAAE;QACxE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,EAAE,MAAwB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;QAC1G,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjI,MAAM,OAAO,GAAG,WAAW,CACzB,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,EACnE,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CACvF,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LabelId, LabelValueId } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import { type DomainError } from '../shared/errors.js';
|
|
4
|
+
import { type Result } from '../shared/result.js';
|
|
5
|
+
import type { FleetListing } from './ports.js';
|
|
6
|
+
export type FindLabelValue = (caller: Caller, input: {
|
|
7
|
+
key: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}) => Promise<Result<{
|
|
10
|
+
labelId: LabelId;
|
|
11
|
+
valueId: LabelValueId;
|
|
12
|
+
}, DomainError<'LABEL_VALUE_NOT_FOUND'>>>;
|
|
13
|
+
/**
|
|
14
|
+
* Use case: the ids of a label and one of its values, by the texts people
|
|
15
|
+
* write, so a caller that knows `os=macos` can assign and select by id
|
|
16
|
+
* (decision 0031). Keys and values are lowercase, so both texts are
|
|
17
|
+
* lowercased, then matched exactly. The caller's scope (fleet:read) is
|
|
18
|
+
* checked before this runs.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createFindLabelValue(deps: {
|
|
21
|
+
listing: Pick<FleetListing, 'labels'>;
|
|
22
|
+
}): FindLabelValue;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
/**
|
|
4
|
+
* Use case: the ids of a label and one of its values, by the texts people
|
|
5
|
+
* write, so a caller that knows `os=macos` can assign and select by id
|
|
6
|
+
* (decision 0031). Keys and values are lowercase, so both texts are
|
|
7
|
+
* lowercased, then matched exactly. The caller's scope (fleet:read) is
|
|
8
|
+
* checked before this runs.
|
|
9
|
+
*/
|
|
10
|
+
export function createFindLabelValue(deps) {
|
|
11
|
+
return async (caller, input) => {
|
|
12
|
+
const key = input.key.toLowerCase();
|
|
13
|
+
const value = input.value.toLowerCase();
|
|
14
|
+
const label = (await deps.listing.labels(caller.fleetId)).find((listed) => listed.key === key);
|
|
15
|
+
const found = label?.values.find((held) => held.value === value);
|
|
16
|
+
return label && found ? ok({ labelId: label.id, valueId: found.id }) : refuse('LABEL_VALUE_NOT_FOUND', `The fleet has no label value ${input.key}=${input.value}`);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=find-label-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-label-value.js","sourceRoot":"","sources":["../../../src/domain/registry/find-label-value.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAQtD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAA+C;IAClF,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QACjE,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACrK,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -25,7 +25,7 @@ export type GetShip = (caller: Caller, input: {
|
|
|
25
25
|
}) => Promise<Result<ShipDetail, DomainError<'SHIP_NOT_FOUND' | 'CREW_REQUEST_NOT_ASSIGNED_TO_CALLER'>>>;
|
|
26
26
|
/**
|
|
27
27
|
* Use case: one ship of the caller's fleet, retired ships included: they keep
|
|
28
|
-
* their page. The caller's scope (fleet:read
|
|
28
|
+
* their page. The caller's scope (fleet:read or crew:run) is
|
|
29
29
|
* checked before this runs; crew:run reads only the ships whose crew requests
|
|
30
30
|
* are assigned to the caller's ship.
|
|
31
31
|
*/
|
|
@@ -3,10 +3,10 @@ import { ok } from '../shared/result.js';
|
|
|
3
3
|
import { listedShipOf } from './list-fleet.js';
|
|
4
4
|
import { checkReaches } from './crew-request.js';
|
|
5
5
|
/** The scopes that read every ship; crew:run reads only the ships assigned to the caller's ship. */
|
|
6
|
-
const READ_SCOPES = ['fleet:read'
|
|
6
|
+
const READ_SCOPES = ['fleet:read'];
|
|
7
7
|
/**
|
|
8
8
|
* Use case: one ship of the caller's fleet, retired ships included: they keep
|
|
9
|
-
* their page. The caller's scope (fleet:read
|
|
9
|
+
* their page. The caller's scope (fleet:read or crew:run) is
|
|
10
10
|
* checked before this runs; crew:run reads only the ships whose crew requests
|
|
11
11
|
* are assigned to the caller's ship.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/get-ship.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAmB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAoB,MAAM,mBAAmB,CAAC;AAwBnE,oGAAoG;AACpG,MAAM,WAAW,GAAG,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"get-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/get-ship.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAmB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAoB,MAAM,mBAAmB,CAAC;AAwBnE,oGAAoG;AACpG,MAAM,WAAW,GAAG,CAAC,YAAY,CAAU,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAA+B;IAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,MAAM,CAAC,gBAAgB,EAAE,WAAW,MAAM,gBAAgB,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;QACjH,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzE,OAAO,EAAE,CAAC;YACR,GAAG,MAAM;YACT,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,IAAI,IAAI;YACvC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE;YACvH,kBAAkB,EAAE,MAAM,CAAC,QAAQ;YACnC,cAAc,EAAE,MAAM,CAAC,IAAI;YAC3B,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS;YACpC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,IAAI;SAChD,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -8,8 +8,8 @@ import { issueStartingPrompt } from './starting-prompt.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Use case: a new starting prompt for a ship of the caller's fleet that awaits
|
|
10
10
|
* crew. Its new secret invalidates any earlier one, so at most one is valid; a
|
|
11
|
-
* prompt lost before use costs nothing. The caller's scope (fleet:manage
|
|
12
|
-
*
|
|
11
|
+
* prompt lost before use costs nothing. The caller's scope (fleet:manage or
|
|
12
|
+
* crew:run) is checked before this runs; crew:run reaches only
|
|
13
13
|
* the ships whose crew requests are assigned to the caller's ship.
|
|
14
14
|
*
|
|
15
15
|
* Locks in the fleet's order: the ship first, so concurrent prompts for one
|
|
@@ -19,7 +19,7 @@ import { issueStartingPrompt } from './starting-prompt.js';
|
|
|
19
19
|
* back.
|
|
20
20
|
*/
|
|
21
21
|
/** The scopes that reach every ship for a starting prompt; crew:run reaches only assigned ones. */
|
|
22
|
-
const PROMPT_SCOPES = ['fleet:manage'
|
|
22
|
+
const PROMPT_SCOPES = ['fleet:manage'];
|
|
23
23
|
export function createGetStartingPrompt(deps) {
|
|
24
24
|
return (caller, { shipId }) => deps.uow.run(async (tx) => {
|
|
25
25
|
const { fleetId } = caller;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-starting-prompt.js","sourceRoot":"","sources":["../../../src/domain/registry/get-starting-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG3E,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAoD,MAAM,sBAAsB,CAAC;AAiB7G;;;;;;;;;;;;GAYG;AACH,mGAAmG;AACnG,MAAM,aAAa,GAAG,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"get-starting-prompt.js","sourceRoot":"","sources":["../../../src/domain/registry/get-starting-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG3E,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAoD,MAAM,sBAAsB,CAAC;AAiB7G;;;;;;;;;;;;GAYG;AACH,mGAAmG;AACnG,MAAM,aAAa,GAAG,CAAC,cAAc,CAAU,CAAC;AAEhD,MAAM,UAAU,uBAAuB,CAAC,IAKvC;IACC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAmE,EAAE;QACzF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,MAAM,CAAC,gBAAgB,EAAE,QAAQ,MAAM,iBAAiB,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;QACjI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,mBAAmB,CACtC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EACnD,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAC/B,CAAC;QACF,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
|