@spinekit/assets 0.1.1 → 0.1.2
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/CHANGELOG.md +11 -0
- package/dist/index.d.mts +32 -7
- package/dist/index.mjs +97 -80
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.2 — 2026-08-26
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **Module split** — `index.ts` monolith decomposed into `src/module.ts`,
|
|
8
|
+
`src/types.ts`, and `src/resources/fixed-asset/`. Public API unchanged;
|
|
9
|
+
the barrel re-exports all the same names. Also adds `createAssetResource`
|
|
10
|
+
as a named export for hosts that compose the resource separately.
|
|
11
|
+
- **Peer floors raised** — `@classytic/assets` `>=0.5.1`,
|
|
12
|
+
`@spinekit/kit` `>=0.3.0`.
|
|
13
|
+
|
|
3
14
|
## 0.1.1 — 2026-08-20
|
|
4
15
|
|
|
5
16
|
### Changed
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { SpineTenantInput } from "@spinekit/kit/tenant";
|
|
2
1
|
import { AssetsContext, AssetsEngine, LedgerPort } from "@classytic/assets";
|
|
3
|
-
import {
|
|
4
|
-
import { PermissionGate } from "@spinekit/kit/permissions";
|
|
2
|
+
import { SpineTenantInput } from "@spinekit/kit/tenant";
|
|
5
3
|
import { EventTransport } from "@classytic/primitives/events";
|
|
6
4
|
import { OutboxStore } from "@classytic/primitives/outbox";
|
|
7
|
-
import {
|
|
5
|
+
import { PermissionGate } from "@spinekit/kit/permissions";
|
|
8
6
|
import { FastifyInstance } from "fastify";
|
|
7
|
+
import { Connection } from "mongoose";
|
|
8
|
+
import { ScheduleDefinition } from "@classytic/arc/plugins";
|
|
9
9
|
//#region src/schedules.d.ts
|
|
10
10
|
interface AssetsMaintenanceOptions {
|
|
11
11
|
/** Automated depreciation posting sweep interval. Default daily (with jitter). */
|
|
@@ -21,7 +21,7 @@ interface AssetsMaintenanceOptions {
|
|
|
21
21
|
}
|
|
22
22
|
declare function assetsMaintenanceSchedules(engine: AssetsEngine, options?: AssetsMaintenanceOptions): ScheduleDefinition[];
|
|
23
23
|
//#endregion
|
|
24
|
-
//#region src/
|
|
24
|
+
//#region src/types.d.ts
|
|
25
25
|
interface AssetsPermissions {
|
|
26
26
|
/** Read register / schedules / valuations. */
|
|
27
27
|
view: PermissionGate;
|
|
@@ -73,6 +73,15 @@ interface AssetsModuleDeps {
|
|
|
73
73
|
* this cannot become a production hot-reload path.)
|
|
74
74
|
*/
|
|
75
75
|
forceRecreate?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Mongoose `autoIndex` for every managed schema. Default `true`
|
|
78
|
+
* (`@classytic/assets`'s own default — sensible for the package used
|
|
79
|
+
* standalone). Never forwarded from this module until now, so a deployment
|
|
80
|
+
* running `shouldAutoIndex()`-gated indexing everywhere else
|
|
81
|
+
* (`#shared/db/auto-index.js`) had no way to reach it here, and the fixed-asset
|
|
82
|
+
* collections re-synced their indexes against Atlas on every boot regardless.
|
|
83
|
+
*/
|
|
84
|
+
autoIndex?: boolean;
|
|
76
85
|
/**
|
|
77
86
|
* Accept a backend without multi-document transactions. DEV/TEST ONLY.
|
|
78
87
|
*
|
|
@@ -91,6 +100,23 @@ interface AssetsModuleDeps {
|
|
|
91
100
|
*/
|
|
92
101
|
maintenance?: AssetsMaintenanceOptions | false;
|
|
93
102
|
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/module.d.ts
|
|
105
|
+
/**
|
|
106
|
+
* @spinekit/assets - fixed-asset register + multi-book depreciation +
|
|
107
|
+
* IAS 16/36 valuation over the @classytic/assets 0.3 mongokit engine.
|
|
108
|
+
*
|
|
109
|
+
* One composition surface (wiki/modules.md): createAssetsModule(deps).
|
|
110
|
+
* The kernel owns models/repos/services + the LedgerPort contract; this
|
|
111
|
+
* module owns the WIRE (CRUD + 12 lifecycle/valuation actions + onboard +
|
|
112
|
+
* schedule/valuation reads). The GL ACCOUNT MAP stays HOST policy - the
|
|
113
|
+
* host implements LedgerPort.postEntry (category -> chart account) and
|
|
114
|
+
* injects it. Company-wide register by default (tenant disabled);
|
|
115
|
+
* currency is host config; category enum is host policy.
|
|
116
|
+
*/
|
|
117
|
+
declare function createAssetsModule(deps: AssetsModuleDeps): import("@classytic/arc/factory").ArcModule<AssetsEngine>;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/resources/fixed-asset/fixed-asset.resource.d.ts
|
|
94
120
|
/**
|
|
95
121
|
* Build the fixed-asset resource over a live assets engine. Exported so a
|
|
96
122
|
* host can mount it directly (custom module composition).
|
|
@@ -105,6 +131,5 @@ declare function createAssetResource(args: {
|
|
|
105
131
|
}): import("@classytic/arc").ResourceDefinition<import("@classytic/assets").AssetDocument | (import("mongoose").Document<unknown, {}, import("@classytic/assets").AssetDocument, {}, import("mongoose").DefaultSchemaOptions> & import("@classytic/assets").Asset & import("mongoose").Document<import("mongoose").Types.ObjectId, any, any, Record<string, any>, {}> & {
|
|
106
132
|
id: string;
|
|
107
133
|
})>;
|
|
108
|
-
declare function createAssetsModule(deps: AssetsModuleDeps): import("@classytic/arc/factory").ArcModule<AssetsEngine>;
|
|
109
134
|
//#endregion
|
|
110
|
-
export { type AssetsMaintenanceOptions, AssetsModuleDeps, AssetsPermissions, assetsMaintenanceSchedules, createAssetResource, createAssetsModule };
|
|
135
|
+
export { type AssetsMaintenanceOptions, type AssetsModuleDeps, type AssetsPermissions, assetsMaintenanceSchedules, createAssetResource, createAssetsModule };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEPRECIATION_METHODS, defineAssets } from "@classytic/assets";
|
|
1
2
|
import { defineEngineModule } from "@spinekit/kit/engine-module";
|
|
2
3
|
import { resolveSpineTenant } from "@spinekit/kit/tenant";
|
|
3
4
|
import { defineResource } from "@classytic/arc";
|
|
@@ -6,48 +7,9 @@ import { scopeFirstCtx } from "@classytic/arc/scope";
|
|
|
6
7
|
import { ValidationError } from "@classytic/arc/utils";
|
|
7
8
|
import { createMongooseAdapter } from "@classytic/mongokit/adapter";
|
|
8
9
|
import { QueryParser } from "@classytic/mongokit";
|
|
9
|
-
import { DEPRECIATION_METHODS, defineAssets } from "@classytic/assets";
|
|
10
10
|
import { isCurrencyCode } from "@classytic/primitives/currency";
|
|
11
11
|
import { money } from "@classytic/primitives/money";
|
|
12
|
-
//#region src/
|
|
13
|
-
const DAY = 864e5;
|
|
14
|
-
function assetsMaintenanceSchedules(engine, options = {}) {
|
|
15
|
-
return [{
|
|
16
|
-
name: "assets.depreciation",
|
|
17
|
-
every: options.depreciationEvery ?? DAY,
|
|
18
|
-
leaseMs: Math.floor((options.depreciationEvery ?? DAY) * .9),
|
|
19
|
-
jitterMs: 9e5,
|
|
20
|
-
handler: async (fastify) => {
|
|
21
|
-
const ctx = {
|
|
22
|
-
actorId: "cron",
|
|
23
|
-
...options.context
|
|
24
|
-
};
|
|
25
|
-
const now = /* @__PURE__ */ new Date();
|
|
26
|
-
const active = await engine.models.FixedAsset.find({
|
|
27
|
-
status: "active",
|
|
28
|
-
deletedAt: null
|
|
29
|
-
}).select("_id name").lean();
|
|
30
|
-
let posted = 0;
|
|
31
|
-
for (const asset of active) try {
|
|
32
|
-
const schedule = await engine.repositories.schedule.findByAssetAndBook(String(asset._id), "accounting", ctx);
|
|
33
|
-
if (!schedule) continue;
|
|
34
|
-
const due = schedule.periods.filter((per) => per.status === "scheduled" && new Date(per.periodEnd) <= now).sort((a, b) => a.sequence - b.sequence);
|
|
35
|
-
for (const per of due) {
|
|
36
|
-
await engine.services.depreciation.postPeriod(String(asset._id), per.sequence, {}, ctx);
|
|
37
|
-
posted += 1;
|
|
38
|
-
}
|
|
39
|
-
} catch (err) {
|
|
40
|
-
fastify.log.error({
|
|
41
|
-
err,
|
|
42
|
-
assetId: String(asset._id)
|
|
43
|
-
}, "Depreciation posting failed for asset");
|
|
44
|
-
}
|
|
45
|
-
if (posted > 0) fastify.log.info({ posted }, "Depreciation periods auto-posted");
|
|
46
|
-
}
|
|
47
|
-
}];
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/index.ts
|
|
12
|
+
//#region src/resources/fixed-asset/fixed-asset.schema.ts
|
|
51
13
|
const createAssetWireBody = {
|
|
52
14
|
type: "object",
|
|
53
15
|
required: [
|
|
@@ -136,6 +98,47 @@ const updateAssetWireBody = {
|
|
|
136
98
|
}
|
|
137
99
|
}
|
|
138
100
|
};
|
|
101
|
+
const DEPRECIATION_SCHEMA = {
|
|
102
|
+
type: "object",
|
|
103
|
+
required: ["method", "periods"],
|
|
104
|
+
properties: {
|
|
105
|
+
method: {
|
|
106
|
+
type: "string",
|
|
107
|
+
enum: [
|
|
108
|
+
"straight_line",
|
|
109
|
+
"declining_balance",
|
|
110
|
+
"double_declining",
|
|
111
|
+
"sum_of_years_digits",
|
|
112
|
+
"units_of_production",
|
|
113
|
+
"manual"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
periods: {
|
|
117
|
+
type: "integer",
|
|
118
|
+
minimum: 1,
|
|
119
|
+
maximum: 1200
|
|
120
|
+
},
|
|
121
|
+
decliningRate: {
|
|
122
|
+
type: "number",
|
|
123
|
+
exclusiveMinimum: 0,
|
|
124
|
+
maximum: 1
|
|
125
|
+
},
|
|
126
|
+
totalUnits: {
|
|
127
|
+
type: "integer",
|
|
128
|
+
minimum: 1
|
|
129
|
+
},
|
|
130
|
+
manualSchedule: {
|
|
131
|
+
type: "array",
|
|
132
|
+
items: {
|
|
133
|
+
type: "integer",
|
|
134
|
+
minimum: 0
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
additionalProperties: false
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/resources/fixed-asset/fixed-asset.resource.ts
|
|
139
142
|
/**
|
|
140
143
|
* Build the fixed-asset resource over a live assets engine. Exported so a
|
|
141
144
|
* host can mount it directly (custom module composition).
|
|
@@ -165,45 +168,6 @@ function createAssetResource(args) {
|
|
|
165
168
|
* resolver serves routes, actions, and controller overrides alike.
|
|
166
169
|
*/
|
|
167
170
|
const ctxOf = (req) => scopeFirstCtx(req, { fallbackActorId: "system" });
|
|
168
|
-
const DEPRECIATION_SCHEMA = {
|
|
169
|
-
type: "object",
|
|
170
|
-
required: ["method", "periods"],
|
|
171
|
-
properties: {
|
|
172
|
-
method: {
|
|
173
|
-
type: "string",
|
|
174
|
-
enum: [
|
|
175
|
-
"straight_line",
|
|
176
|
-
"declining_balance",
|
|
177
|
-
"double_declining",
|
|
178
|
-
"sum_of_years_digits",
|
|
179
|
-
"units_of_production",
|
|
180
|
-
"manual"
|
|
181
|
-
]
|
|
182
|
-
},
|
|
183
|
-
periods: {
|
|
184
|
-
type: "integer",
|
|
185
|
-
minimum: 1,
|
|
186
|
-
maximum: 1200
|
|
187
|
-
},
|
|
188
|
-
decliningRate: {
|
|
189
|
-
type: "number",
|
|
190
|
-
exclusiveMinimum: 0,
|
|
191
|
-
maximum: 1
|
|
192
|
-
},
|
|
193
|
-
totalUnits: {
|
|
194
|
-
type: "integer",
|
|
195
|
-
minimum: 1
|
|
196
|
-
},
|
|
197
|
-
manualSchedule: {
|
|
198
|
-
type: "array",
|
|
199
|
-
items: {
|
|
200
|
-
type: "integer",
|
|
201
|
-
minimum: 0
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
additionalProperties: false
|
|
206
|
-
};
|
|
207
171
|
/**
|
|
208
172
|
* CREATE is the domain verb, declared as a WRITE VERB (arc 2.34 `writes`)
|
|
209
173
|
* rather than a controller override.
|
|
@@ -753,6 +717,58 @@ function createAssetResource(args) {
|
|
|
753
717
|
]
|
|
754
718
|
});
|
|
755
719
|
}
|
|
720
|
+
//#endregion
|
|
721
|
+
//#region src/schedules.ts
|
|
722
|
+
const DAY = 864e5;
|
|
723
|
+
function assetsMaintenanceSchedules(engine, options = {}) {
|
|
724
|
+
return [{
|
|
725
|
+
name: "assets.depreciation",
|
|
726
|
+
every: options.depreciationEvery ?? DAY,
|
|
727
|
+
leaseMs: Math.floor((options.depreciationEvery ?? DAY) * .9),
|
|
728
|
+
jitterMs: 9e5,
|
|
729
|
+
handler: async (fastify) => {
|
|
730
|
+
const ctx = {
|
|
731
|
+
actorId: "cron",
|
|
732
|
+
...options.context
|
|
733
|
+
};
|
|
734
|
+
const now = /* @__PURE__ */ new Date();
|
|
735
|
+
const active = await engine.models.FixedAsset.find({
|
|
736
|
+
status: "active",
|
|
737
|
+
deletedAt: null
|
|
738
|
+
}).select("_id name").lean();
|
|
739
|
+
let posted = 0;
|
|
740
|
+
for (const asset of active) try {
|
|
741
|
+
const schedule = await engine.repositories.schedule.findByAssetAndBook(String(asset._id), "accounting", ctx);
|
|
742
|
+
if (!schedule) continue;
|
|
743
|
+
const due = schedule.periods.filter((per) => per.status === "scheduled" && new Date(per.periodEnd) <= now).sort((a, b) => a.sequence - b.sequence);
|
|
744
|
+
for (const per of due) {
|
|
745
|
+
await engine.services.depreciation.postPeriod(String(asset._id), per.sequence, {}, ctx);
|
|
746
|
+
posted += 1;
|
|
747
|
+
}
|
|
748
|
+
} catch (err) {
|
|
749
|
+
fastify.log.error({
|
|
750
|
+
err,
|
|
751
|
+
assetId: String(asset._id)
|
|
752
|
+
}, "Depreciation posting failed for asset");
|
|
753
|
+
}
|
|
754
|
+
if (posted > 0) fastify.log.info({ posted }, "Depreciation periods auto-posted");
|
|
755
|
+
}
|
|
756
|
+
}];
|
|
757
|
+
}
|
|
758
|
+
//#endregion
|
|
759
|
+
//#region src/module.ts
|
|
760
|
+
/**
|
|
761
|
+
* @spinekit/assets - fixed-asset register + multi-book depreciation +
|
|
762
|
+
* IAS 16/36 valuation over the @classytic/assets 0.3 mongokit engine.
|
|
763
|
+
*
|
|
764
|
+
* One composition surface (wiki/modules.md): createAssetsModule(deps).
|
|
765
|
+
* The kernel owns models/repos/services + the LedgerPort contract; this
|
|
766
|
+
* module owns the WIRE (CRUD + 12 lifecycle/valuation actions + onboard +
|
|
767
|
+
* schedule/valuation reads). The GL ACCOUNT MAP stays HOST policy - the
|
|
768
|
+
* host implements LedgerPort.postEntry (category -> chart account) and
|
|
769
|
+
* injects it. Company-wide register by default (tenant disabled);
|
|
770
|
+
* currency is host config; category enum is host policy.
|
|
771
|
+
*/
|
|
756
772
|
function createAssetsModule(deps) {
|
|
757
773
|
const maintenance = deps.maintenance;
|
|
758
774
|
const dependsOn = deps.dependsOn ?? (typeof deps.ledger === "function" ? ["accounting"] : []);
|
|
@@ -788,7 +804,8 @@ function createAssetsModule(deps) {
|
|
|
788
804
|
return defineAssets({
|
|
789
805
|
tenant: resolveSpineTenant(deps.tenant ?? false).input,
|
|
790
806
|
...deps.schemaOptions ? { schemaOptions: deps.schemaOptions } : {},
|
|
791
|
-
...deps.forceRecreate !== void 0 ? { forceRecreate: deps.forceRecreate } : {}
|
|
807
|
+
...deps.forceRecreate !== void 0 ? { forceRecreate: deps.forceRecreate } : {},
|
|
808
|
+
...deps.autoIndex !== void 0 ? { autoIndex: deps.autoIndex } : {}
|
|
792
809
|
}).bind(deps.connection, {
|
|
793
810
|
...ledger ? { bridges: { ledger } } : {},
|
|
794
811
|
...deps.eventTransport ? { eventTransport: deps.eventTransport } : {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spinekit/assets",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Arc module for @classytic/assets — fixed-asset register + multi-book depreciation + IAS 16/36 valuation as composable resources. BYO-engine or module-created; ledger bridge is host-injected (any chart of accounts). Depreciation posts through the bridge; GL account mapping stays host policy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -19,18 +19,18 @@
|
|
|
19
19
|
"CHANGELOG.md"
|
|
20
20
|
],
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@classytic/arc": ">=2.
|
|
23
|
-
"@
|
|
24
|
-
"@classytic/
|
|
25
|
-
"@
|
|
22
|
+
"@classytic/arc": ">=2.35.0",
|
|
23
|
+
"@classytic/assets": ">=0.5.1",
|
|
24
|
+
"@classytic/mongokit": ">=3.35.0",
|
|
25
|
+
"@spinekit/kit": ">=0.3.0",
|
|
26
26
|
"mongoose": ">=9.4.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@classytic/arc": "^2.
|
|
29
|
+
"@classytic/arc": "^2.35.0",
|
|
30
30
|
"@classytic/arc-testkit": "^0.4.0",
|
|
31
|
-
"@classytic/assets": ">=0.5.
|
|
32
|
-
"@classytic/mongokit": "
|
|
33
|
-
"@classytic/primitives": ">=0.
|
|
31
|
+
"@classytic/assets": ">=0.5.1",
|
|
32
|
+
"@classytic/mongokit": "^3.35.0",
|
|
33
|
+
"@classytic/primitives": ">=0.25.0",
|
|
34
34
|
"@types/node": "^24.3.0",
|
|
35
35
|
"fastify": "^5.12.0",
|
|
36
36
|
"mongodb-memory-server": "^10.4.3",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"tsdown": "^0.22.14",
|
|
39
39
|
"typescript": "^7.0.2",
|
|
40
40
|
"vitest": "^3.2.4",
|
|
41
|
-
"@spinekit/kit": "0.
|
|
41
|
+
"@spinekit/kit": "0.3.0"
|
|
42
42
|
},
|
|
43
43
|
"author": "Classytic",
|
|
44
44
|
"homepage": "https://www.npmjs.com/package/@spinekit/assets",
|