ofcoop-shared-core 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +18 -0
  2. package/dist/OfcoopCore.d.ts +60 -0
  3. package/dist/OfcoopCore.js +273 -0
  4. package/dist/contracts/MemberContract.d.ts +52 -0
  5. package/dist/contracts/MemberContract.js +2 -0
  6. package/dist/contracts/MemberNumberPolicyContract.d.ts +44 -0
  7. package/dist/contracts/MemberNumberPolicyContract.js +2 -0
  8. package/dist/contracts/SavingComplianceSnapshotContract.d.ts +34 -0
  9. package/dist/contracts/SavingComplianceSnapshotContract.js +2 -0
  10. package/dist/contracts/SavingLedgerContract.d.ts +49 -0
  11. package/dist/contracts/SavingLedgerContract.js +2 -0
  12. package/dist/contracts/SavingPolicyContract.d.ts +63 -0
  13. package/dist/contracts/SavingPolicyContract.js +2 -0
  14. package/dist/contracts/ShuConfigContract.d.ts +39 -0
  15. package/dist/contracts/ShuConfigContract.js +2 -0
  16. package/dist/contracts/ShuContract.d.ts +58 -0
  17. package/dist/contracts/ShuContract.js +2 -0
  18. package/dist/contracts/crossDomainPrimitives.d.ts +5 -0
  19. package/dist/contracts/crossDomainPrimitives.js +2 -0
  20. package/dist/data/applyPendingMigrations.d.ts +2 -0
  21. package/dist/data/applyPendingMigrations.js +30 -0
  22. package/dist/data/migrations.d.ts +2 -0
  23. package/dist/data/migrations.js +20 -0
  24. package/dist/data/repositories.d.ts +114 -0
  25. package/dist/data/repositories.js +324 -0
  26. package/dist/data/schemas.d.ts +14 -0
  27. package/dist/data/schemas.js +179 -0
  28. package/dist/index.d.ts +38 -0
  29. package/dist/index.js +54 -0
  30. package/dist/services/AuditTrailQueryService.d.ts +35 -0
  31. package/dist/services/AuditTrailQueryService.js +62 -0
  32. package/dist/services/CoopOrchestrationService.d.ts +35 -0
  33. package/dist/services/CoopOrchestrationService.js +71 -0
  34. package/dist/services/DailyOpsService.d.ts +2 -0
  35. package/dist/services/DailyOpsService.js +7 -0
  36. package/dist/services/DashboardSummaryService.d.ts +180 -0
  37. package/dist/services/DashboardSummaryService.js +211 -0
  38. package/dist/services/DashboardViewModelService.d.ts +42 -0
  39. package/dist/services/DashboardViewModelService.js +193 -0
  40. package/dist/services/Member360Service.d.ts +75 -0
  41. package/dist/services/Member360Service.js +79 -0
  42. package/dist/services/Member360ViewModelService.d.ts +33 -0
  43. package/dist/services/Member360ViewModelService.js +66 -0
  44. package/dist/services/MemberNumberPolicyService.d.ts +4 -0
  45. package/dist/services/MemberNumberPolicyService.js +18 -0
  46. package/dist/services/MemberService.d.ts +4 -0
  47. package/dist/services/MemberService.js +18 -0
  48. package/dist/services/ReportSummaryService.d.ts +81 -0
  49. package/dist/services/ReportSummaryService.js +160 -0
  50. package/dist/services/ReportViewModelService.d.ts +24 -0
  51. package/dist/services/ReportViewModelService.js +90 -0
  52. package/dist/services/SavingComplianceSnapshotService.d.ts +4 -0
  53. package/dist/services/SavingComplianceSnapshotService.js +10 -0
  54. package/dist/services/SavingLedgerService.d.ts +4 -0
  55. package/dist/services/SavingLedgerService.js +13 -0
  56. package/dist/services/SavingPolicyService.d.ts +5 -0
  57. package/dist/services/SavingPolicyService.js +20 -0
  58. package/dist/services/ShuConfigService.d.ts +4 -0
  59. package/dist/services/ShuConfigService.js +16 -0
  60. package/dist/services/ShuService.d.ts +4 -0
  61. package/dist/services/ShuService.js +14 -0
  62. package/dist/services/createActivityAuditTrailProvider.d.ts +22 -0
  63. package/dist/services/createActivityAuditTrailProvider.js +73 -0
  64. package/dist/services/createAuditTrailCompositionProvider.d.ts +13 -0
  65. package/dist/services/createAuditTrailCompositionProvider.js +21 -0
  66. package/dist/services/createDbAdapterOfcoopServices.d.ts +20 -0
  67. package/dist/services/createDbAdapterOfcoopServices.js +23 -0
  68. package/dist/services/createMember360CompositionProviders.d.ts +6 -0
  69. package/dist/services/createMember360CompositionProviders.js +43 -0
  70. package/dist/services/createOfauthCompositionProviders.d.ts +39 -0
  71. package/dist/services/createOfauthCompositionProviders.js +80 -0
  72. package/dist/services/createOfcoopCreditCompositionProviders.d.ts +59 -0
  73. package/dist/services/createOfcoopCreditCompositionProviders.js +233 -0
  74. package/dist/services/createOfcoopDashboardCompositionProviders.d.ts +18 -0
  75. package/dist/services/createOfcoopDashboardCompositionProviders.js +228 -0
  76. package/dist/services/createOfcoopDomainAuditCompositionProviders.d.ts +36 -0
  77. package/dist/services/createOfcoopDomainAuditCompositionProviders.js +117 -0
  78. package/dist/services/createOfcoopReportCompositionProviders.d.ts +10 -0
  79. package/dist/services/createOfcoopReportCompositionProviders.js +30 -0
  80. package/dist/services/errors.d.ts +8 -0
  81. package/dist/services/errors.js +23 -0
  82. package/dist/services/impl/DbAdapterMemberNumberPolicyService.d.ts +9 -0
  83. package/dist/services/impl/DbAdapterMemberNumberPolicyService.js +37 -0
  84. package/dist/services/impl/DbAdapterMemberService.d.ts +21 -0
  85. package/dist/services/impl/DbAdapterMemberService.js +142 -0
  86. package/dist/services/impl/DbAdapterSavingComplianceSnapshotService.d.ts +9 -0
  87. package/dist/services/impl/DbAdapterSavingComplianceSnapshotService.js +74 -0
  88. package/dist/services/impl/DbAdapterSavingLedgerService.d.ts +18 -0
  89. package/dist/services/impl/DbAdapterSavingLedgerService.js +115 -0
  90. package/dist/services/impl/DbAdapterSavingPolicyService.d.ts +14 -0
  91. package/dist/services/impl/DbAdapterSavingPolicyService.js +139 -0
  92. package/dist/services/impl/DbAdapterShuConfigService.d.ts +12 -0
  93. package/dist/services/impl/DbAdapterShuConfigService.js +62 -0
  94. package/dist/services/impl/DbAdapterShuService.d.ts +26 -0
  95. package/dist/services/impl/DbAdapterShuService.js +376 -0
  96. package/dist/services/impl/runtimeSupport.d.ts +18 -0
  97. package/dist/services/impl/runtimeSupport.js +29 -0
  98. package/package.json +41 -0
@@ -0,0 +1,58 @@
1
+ export type ShuPeriodStatus = 'draft' | 'finalized';
2
+ export interface ShuPeriodContract {
3
+ id: string;
4
+ periodCode: string;
5
+ startDate: string;
6
+ endDate: string;
7
+ status: ShuPeriodStatus;
8
+ formulaSnapshot: Record<string, unknown>;
9
+ branchId?: string | null;
10
+ tenantId?: string | null;
11
+ version: number;
12
+ lastModified: string;
13
+ deleted: boolean;
14
+ }
15
+ export interface ShuAllocationContract {
16
+ id: string;
17
+ shuPeriodId: string;
18
+ memberId: string;
19
+ allocationAmount: number;
20
+ calculationBasis: Record<string, unknown>;
21
+ branchId?: string | null;
22
+ tenantId?: string | null;
23
+ version: number;
24
+ lastModified: string;
25
+ deleted: boolean;
26
+ }
27
+ export interface CreateShuPeriodInput {
28
+ periodCode: string;
29
+ startDate: string;
30
+ endDate: string;
31
+ formulaSnapshot: Record<string, unknown>;
32
+ branchId?: string | null;
33
+ tenantId?: string | null;
34
+ }
35
+ export interface ShuAllocationQueryOptions {
36
+ includeDeleted?: boolean;
37
+ memberId?: string;
38
+ }
39
+ export interface ShuPeriodQueryOptions {
40
+ includeDeleted?: boolean;
41
+ tenantId?: string | null;
42
+ branchId?: string | null;
43
+ status?: ShuPeriodStatus;
44
+ dateContains?: string;
45
+ }
46
+ export interface CsvExportPayload {
47
+ filename: string;
48
+ contentType: string;
49
+ body: string;
50
+ }
51
+ export interface ShuServiceContract {
52
+ createShuPeriod(input: CreateShuPeriodInput): Promise<ShuPeriodContract>;
53
+ finalizeShuPeriod(periodId: string): Promise<ShuPeriodContract>;
54
+ listShuPeriods(options?: ShuPeriodQueryOptions): Promise<ShuPeriodContract[]>;
55
+ generateShuAllocations(periodId: string): Promise<ShuAllocationContract[]>;
56
+ listShuAllocations(periodId: string, options?: ShuAllocationQueryOptions): Promise<ShuAllocationContract[]>;
57
+ exportShuAllocationsCsv(periodId: string): Promise<CsvExportPayload>;
58
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Bridge file for RFC 005 adoption.
3
+ * Source of truth remains in `ofcore`.
4
+ */
5
+ export type { ScopeRef, DomainAuditActor, DomainAuditEntityRef, DomainAuditEvent, WorklistUrgency, WorklistItem, PolicyVersionedConfig, ComplianceEvaluationResult, } from 'ofcore';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { DbAdapter, LoggerAdapter } from 'ofcore';
2
+ export declare function applyPendingMigrations(adapter: DbAdapter, logger?: LoggerAdapter): Promise<void>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyPendingMigrations = applyPendingMigrations;
4
+ const migrations_1 = require("./migrations");
5
+ const noopLogger = {
6
+ logInfo() { },
7
+ logWarn() { },
8
+ logError() { },
9
+ };
10
+ async function applyPendingMigrations(adapter, logger = noopLogger) {
11
+ logger.logInfo('[ofcoop] starting database migration process');
12
+ const sorted = [...migrations_1.migrations].sort((a, b) => a.toVersion - b.toVersion);
13
+ const targetVersion = sorted.length > 0 ? sorted[sorted.length - 1].toVersion : 0;
14
+ let currentVersion = await adapter.getSchemaVersion();
15
+ if (currentVersion == null || currentVersion < 0)
16
+ currentVersion = 0;
17
+ if (currentVersion >= targetVersion) {
18
+ logger.logInfo(`[ofcoop] database already up-to-date at v${currentVersion}`);
19
+ return;
20
+ }
21
+ for (const migration of sorted) {
22
+ if (migration.toVersion > currentVersion) {
23
+ logger.logInfo(`[ofcoop] applying migration v${migration.toVersion}`);
24
+ await migration.up(adapter);
25
+ await adapter.setSchemaVersion(migration.toVersion);
26
+ currentVersion = migration.toVersion;
27
+ }
28
+ }
29
+ logger.logInfo(`[ofcoop] migration completed at v${currentVersion}`);
30
+ }
@@ -0,0 +1,2 @@
1
+ import type { Migration } from 'ofcore';
2
+ export declare const migrations: Migration[];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrations = void 0;
4
+ const schemas_1 = require("./schemas");
5
+ exports.migrations = [
6
+ {
7
+ toVersion: 1,
8
+ up: async (adapter) => {
9
+ const tables = (0, schemas_1.getOfcoopTableSchemas)();
10
+ for (const table of tables) {
11
+ try {
12
+ await adapter.addTable(table);
13
+ }
14
+ catch {
15
+ // Adapter may throw when table already exists; migration stays idempotent.
16
+ }
17
+ }
18
+ },
19
+ },
20
+ ];
@@ -0,0 +1,114 @@
1
+ import type { DbAdapter } from 'ofcore';
2
+ import type { MemberContract, MemberExitInput, MemberQueryOptions, MemberWaConsentInput } from '../contracts/MemberContract';
3
+ import type { MemberNumberPolicyContract, MemberNumberPolicyScope } from '../contracts/MemberNumberPolicyContract';
4
+ import type { SavingLedgerContract, SavingLedgerQueryOptions } from '../contracts/SavingLedgerContract';
5
+ import type { SavingPolicyContract, SavingPolicyScope } from '../contracts/SavingPolicyContract';
6
+ import type { ShuAllocationContract, ShuAllocationQueryOptions, ShuPeriodContract } from '../contracts/ShuContract';
7
+ import type { ShuConfigContract, ShuConfigQueryOptions, ShuConfigScope } from '../contracts/ShuConfigContract';
8
+ interface MemberExitStateRow {
9
+ id: string;
10
+ stage: 'requested' | 'settled' | 'canceled';
11
+ reason?: string | null;
12
+ requestedBy?: string | null;
13
+ referenceId?: string | null;
14
+ version: number;
15
+ lastModified: string;
16
+ deleted: boolean;
17
+ }
18
+ interface MemberWaConsentRow {
19
+ id: string;
20
+ granted: boolean;
21
+ source?: string | null;
22
+ note?: string | null;
23
+ version: number;
24
+ lastModified: string;
25
+ deleted: boolean;
26
+ }
27
+ export declare class MemberRepository {
28
+ private readonly db;
29
+ constructor(db: DbAdapter);
30
+ create(row: MemberContract): Promise<MemberContract>;
31
+ update(id: string, updates: Partial<MemberContract>): Promise<MemberContract>;
32
+ getById(id: string): Promise<MemberContract | null>;
33
+ list(options?: MemberQueryOptions): Promise<MemberContract[]>;
34
+ }
35
+ export declare class MemberWaConsentRepository {
36
+ private readonly db;
37
+ constructor(db: DbAdapter);
38
+ set(memberId: string, consent: MemberWaConsentInput): Promise<MemberWaConsentRow>;
39
+ get(memberId: string): Promise<MemberWaConsentRow | null>;
40
+ }
41
+ export declare class MemberExitStateRepository {
42
+ private readonly db;
43
+ constructor(db: DbAdapter);
44
+ set(memberId: string, stage: MemberExitStateRow['stage'], payload: MemberExitInput): Promise<MemberExitStateRow>;
45
+ get(memberId: string): Promise<MemberExitStateRow | null>;
46
+ }
47
+ export declare class MemberNumberPolicyRepository {
48
+ private readonly db;
49
+ constructor(db: DbAdapter);
50
+ upsert(policy: MemberNumberPolicyContract): Promise<MemberNumberPolicyContract>;
51
+ getActive(scope: MemberNumberPolicyScope): Promise<MemberNumberPolicyContract | null>;
52
+ list(scope: MemberNumberPolicyScope): Promise<MemberNumberPolicyContract[]>;
53
+ }
54
+ export declare class SavingPolicyRepository {
55
+ private readonly db;
56
+ constructor(db: DbAdapter);
57
+ upsert(policy: SavingPolicyContract): Promise<SavingPolicyContract>;
58
+ getActive(scope: SavingPolicyScope): Promise<SavingPolicyContract | null>;
59
+ list(scope: SavingPolicyScope): Promise<SavingPolicyContract[]>;
60
+ }
61
+ export declare class SavingLedgerRepository {
62
+ private readonly db;
63
+ constructor(db: DbAdapter);
64
+ create(row: SavingLedgerContract): Promise<SavingLedgerContract>;
65
+ listByMember(memberId: string, options?: SavingLedgerQueryOptions): Promise<SavingLedgerContract[]>;
66
+ listAll(options?: SavingLedgerQueryOptions): Promise<SavingLedgerContract[]>;
67
+ findByReference(input: {
68
+ memberId: string;
69
+ savingType: SavingLedgerContract['savingType'];
70
+ entryType: SavingLedgerContract['entryType'];
71
+ referenceType: string;
72
+ referenceId: string;
73
+ tenantId?: string | null;
74
+ branchId?: string | null;
75
+ }): Promise<SavingLedgerContract | null>;
76
+ }
77
+ export declare class ShuConfigRepository {
78
+ private readonly db;
79
+ constructor(db: DbAdapter);
80
+ upsert(config: ShuConfigContract): Promise<ShuConfigContract>;
81
+ getActive(scope: ShuConfigScope): Promise<ShuConfigContract | null>;
82
+ list(scope: ShuConfigScope, options?: ShuConfigQueryOptions): Promise<ShuConfigContract[]>;
83
+ }
84
+ export declare class ShuPeriodRepository {
85
+ private readonly db;
86
+ constructor(db: DbAdapter);
87
+ create(period: ShuPeriodContract): Promise<ShuPeriodContract>;
88
+ update(id: string, updates: Partial<ShuPeriodContract>): Promise<ShuPeriodContract>;
89
+ getById(id: string): Promise<ShuPeriodContract | null>;
90
+ list(options?: {
91
+ includeDeleted?: boolean;
92
+ tenantId?: string | null;
93
+ branchId?: string | null;
94
+ }): Promise<ShuPeriodContract[]>;
95
+ }
96
+ export declare class ShuAllocationRepository {
97
+ private readonly db;
98
+ constructor(db: DbAdapter);
99
+ createMany(rows: ShuAllocationContract[]): Promise<ShuAllocationContract[]>;
100
+ listByPeriod(periodId: string, options?: ShuAllocationQueryOptions): Promise<ShuAllocationContract[]>;
101
+ }
102
+ export interface OfcoopRepositories {
103
+ memberRepository: MemberRepository;
104
+ memberWaConsentRepository: MemberWaConsentRepository;
105
+ memberExitStateRepository: MemberExitStateRepository;
106
+ memberNumberPolicyRepository: MemberNumberPolicyRepository;
107
+ savingPolicyRepository: SavingPolicyRepository;
108
+ savingLedgerRepository: SavingLedgerRepository;
109
+ shuConfigRepository: ShuConfigRepository;
110
+ shuPeriodRepository: ShuPeriodRepository;
111
+ shuAllocationRepository: ShuAllocationRepository;
112
+ }
113
+ export declare function createOfcoopRepositories(db: DbAdapter): OfcoopRepositories;
114
+ export type { MemberExitStateRow, MemberWaConsentRow };
@@ -0,0 +1,324 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShuAllocationRepository = exports.ShuPeriodRepository = exports.ShuConfigRepository = exports.SavingLedgerRepository = exports.SavingPolicyRepository = exports.MemberNumberPolicyRepository = exports.MemberExitStateRepository = exports.MemberWaConsentRepository = exports.MemberRepository = void 0;
4
+ exports.createOfcoopRepositories = createOfcoopRepositories;
5
+ const schemas_1 = require("./schemas");
6
+ function nowIso() {
7
+ return new Date().toISOString();
8
+ }
9
+ function isEffectiveOn(dateIso, refIso) {
10
+ return new Date(dateIso).getTime() <= new Date(refIso).getTime();
11
+ }
12
+ function toAnd(filters) {
13
+ if (filters.length === 0)
14
+ return undefined;
15
+ if (filters.length === 1)
16
+ return filters[0];
17
+ return { and: filters };
18
+ }
19
+ class MemberRepository {
20
+ constructor(db) {
21
+ this.db = db;
22
+ }
23
+ async create(row) {
24
+ return this.db.create(schemas_1.OFCOOP_TABLES.members, row);
25
+ }
26
+ async update(id, updates) {
27
+ return this.db.update(schemas_1.OFCOOP_TABLES.members, id, updates);
28
+ }
29
+ async getById(id) {
30
+ return this.db.get(schemas_1.OFCOOP_TABLES.members, id);
31
+ }
32
+ async list(options) {
33
+ const filters = [];
34
+ if (!options?.includeDeleted)
35
+ filters.push({ deleted: false });
36
+ if (options?.status)
37
+ filters.push({ status: options.status });
38
+ if (options?.tenantId !== undefined)
39
+ filters.push({ tenantId: options.tenantId ?? null });
40
+ if (options?.branchId !== undefined)
41
+ filters.push({ branchId: options.branchId ?? null });
42
+ return this.db.query(schemas_1.OFCOOP_TABLES.members, {
43
+ filters: toAnd(filters),
44
+ sort: [{ field: 'lastModified', direction: 'desc' }],
45
+ });
46
+ }
47
+ }
48
+ exports.MemberRepository = MemberRepository;
49
+ class MemberWaConsentRepository {
50
+ constructor(db) {
51
+ this.db = db;
52
+ }
53
+ async set(memberId, consent) {
54
+ const current = await this.get(memberId);
55
+ const payload = {
56
+ id: memberId,
57
+ granted: consent.granted,
58
+ source: consent.source ?? null,
59
+ note: consent.note ?? null,
60
+ version: (current?.version ?? 0) + 1,
61
+ lastModified: nowIso(),
62
+ deleted: false,
63
+ };
64
+ if (current) {
65
+ return this.db.update(schemas_1.OFCOOP_TABLES.memberWaConsent, memberId, payload);
66
+ }
67
+ return this.db.create(schemas_1.OFCOOP_TABLES.memberWaConsent, payload);
68
+ }
69
+ async get(memberId) {
70
+ return this.db.get(schemas_1.OFCOOP_TABLES.memberWaConsent, memberId);
71
+ }
72
+ }
73
+ exports.MemberWaConsentRepository = MemberWaConsentRepository;
74
+ class MemberExitStateRepository {
75
+ constructor(db) {
76
+ this.db = db;
77
+ }
78
+ async set(memberId, stage, payload) {
79
+ const current = await this.get(memberId);
80
+ const next = {
81
+ id: memberId,
82
+ stage,
83
+ reason: payload.reason ?? null,
84
+ requestedBy: payload.requestedBy ?? null,
85
+ referenceId: payload.referenceId ?? null,
86
+ version: (current?.version ?? 0) + 1,
87
+ lastModified: nowIso(),
88
+ deleted: false,
89
+ };
90
+ if (current) {
91
+ return this.db.update(schemas_1.OFCOOP_TABLES.memberExitState, memberId, next);
92
+ }
93
+ return this.db.create(schemas_1.OFCOOP_TABLES.memberExitState, next);
94
+ }
95
+ async get(memberId) {
96
+ return this.db.get(schemas_1.OFCOOP_TABLES.memberExitState, memberId);
97
+ }
98
+ }
99
+ exports.MemberExitStateRepository = MemberExitStateRepository;
100
+ class MemberNumberPolicyRepository {
101
+ constructor(db) {
102
+ this.db = db;
103
+ }
104
+ async upsert(policy) {
105
+ const existing = await this.db.get(schemas_1.OFCOOP_TABLES.memberNumberPolicies, policy.id);
106
+ if (existing) {
107
+ return this.db.update(schemas_1.OFCOOP_TABLES.memberNumberPolicies, policy.id, policy);
108
+ }
109
+ return this.db.create(schemas_1.OFCOOP_TABLES.memberNumberPolicies, policy);
110
+ }
111
+ async getActive(scope) {
112
+ const now = nowIso();
113
+ const rows = await this.list(scope);
114
+ return rows
115
+ .filter((row) => isEffectiveOn(row.effectiveDate, now))
116
+ .sort((a, b) => b.effectiveDate.localeCompare(a.effectiveDate))[0] ?? null;
117
+ }
118
+ async list(scope) {
119
+ return this.db.query(schemas_1.OFCOOP_TABLES.memberNumberPolicies, {
120
+ filters: {
121
+ and: [
122
+ { deleted: false },
123
+ { koperasiId: scope.koperasiId },
124
+ { tenantId: scope.tenantId },
125
+ { branchId: scope.branchId ?? null },
126
+ ],
127
+ },
128
+ sort: [{ field: 'effectiveDate', direction: 'desc' }],
129
+ });
130
+ }
131
+ }
132
+ exports.MemberNumberPolicyRepository = MemberNumberPolicyRepository;
133
+ class SavingPolicyRepository {
134
+ constructor(db) {
135
+ this.db = db;
136
+ }
137
+ async upsert(policy) {
138
+ const existing = await this.db.get(schemas_1.OFCOOP_TABLES.savingPolicies, policy.id);
139
+ if (existing) {
140
+ return this.db.update(schemas_1.OFCOOP_TABLES.savingPolicies, policy.id, policy);
141
+ }
142
+ return this.db.create(schemas_1.OFCOOP_TABLES.savingPolicies, policy);
143
+ }
144
+ async getActive(scope) {
145
+ const now = nowIso();
146
+ const rows = await this.list(scope);
147
+ return rows
148
+ .filter((row) => isEffectiveOn(row.effectiveDate, now))
149
+ .sort((a, b) => b.effectiveDate.localeCompare(a.effectiveDate))[0] ?? null;
150
+ }
151
+ async list(scope) {
152
+ return this.db.query(schemas_1.OFCOOP_TABLES.savingPolicies, {
153
+ filters: {
154
+ and: [
155
+ { deleted: false },
156
+ { koperasiId: scope.koperasiId },
157
+ { tenantId: scope.tenantId },
158
+ { branchId: scope.branchId ?? null },
159
+ ],
160
+ },
161
+ sort: [{ field: 'effectiveDate', direction: 'desc' }],
162
+ });
163
+ }
164
+ }
165
+ exports.SavingPolicyRepository = SavingPolicyRepository;
166
+ class SavingLedgerRepository {
167
+ constructor(db) {
168
+ this.db = db;
169
+ }
170
+ async create(row) {
171
+ return this.db.create(schemas_1.OFCOOP_TABLES.savingEntries, row);
172
+ }
173
+ async listByMember(memberId, options) {
174
+ const filters = [{ memberId }];
175
+ if (!options?.includeDeleted)
176
+ filters.push({ deleted: false });
177
+ if (options?.dateFrom)
178
+ filters.push({ field: 'transactionDate', operator: '>=', value: options.dateFrom });
179
+ if (options?.dateTo)
180
+ filters.push({ field: 'transactionDate', operator: '<=', value: options.dateTo });
181
+ if (options?.tenantId !== undefined)
182
+ filters.push({ tenantId: options.tenantId ?? null });
183
+ if (options?.branchId !== undefined)
184
+ filters.push({ branchId: options.branchId ?? null });
185
+ return this.db.query(schemas_1.OFCOOP_TABLES.savingEntries, {
186
+ filters: toAnd(filters),
187
+ sort: [{ field: 'transactionDate', direction: 'desc' }],
188
+ });
189
+ }
190
+ async listAll(options) {
191
+ const filters = [];
192
+ if (!options?.includeDeleted)
193
+ filters.push({ deleted: false });
194
+ if (options?.dateFrom)
195
+ filters.push({ field: 'transactionDate', operator: '>=', value: options.dateFrom });
196
+ if (options?.dateTo)
197
+ filters.push({ field: 'transactionDate', operator: '<=', value: options.dateTo });
198
+ if (options?.tenantId !== undefined)
199
+ filters.push({ tenantId: options.tenantId ?? null });
200
+ if (options?.branchId !== undefined)
201
+ filters.push({ branchId: options.branchId ?? null });
202
+ return this.db.query(schemas_1.OFCOOP_TABLES.savingEntries, {
203
+ filters: toAnd(filters),
204
+ sort: [{ field: 'transactionDate', direction: 'desc' }],
205
+ });
206
+ }
207
+ async findByReference(input) {
208
+ const filters = [
209
+ { deleted: false },
210
+ { memberId: input.memberId },
211
+ { savingType: input.savingType },
212
+ { entryType: input.entryType },
213
+ { referenceType: input.referenceType },
214
+ { referenceId: input.referenceId },
215
+ ];
216
+ if (input.tenantId !== undefined)
217
+ filters.push({ tenantId: input.tenantId ?? null });
218
+ if (input.branchId !== undefined)
219
+ filters.push({ branchId: input.branchId ?? null });
220
+ const rows = await this.db.query(schemas_1.OFCOOP_TABLES.savingEntries, {
221
+ filters: toAnd(filters),
222
+ sort: [{ field: 'lastModified', direction: 'desc' }],
223
+ limit: 1,
224
+ });
225
+ return rows[0] ?? null;
226
+ }
227
+ }
228
+ exports.SavingLedgerRepository = SavingLedgerRepository;
229
+ class ShuConfigRepository {
230
+ constructor(db) {
231
+ this.db = db;
232
+ }
233
+ async upsert(config) {
234
+ const existing = await this.db.get(schemas_1.OFCOOP_TABLES.shuConfigs, config.id);
235
+ if (existing) {
236
+ return this.db.update(schemas_1.OFCOOP_TABLES.shuConfigs, config.id, config);
237
+ }
238
+ return this.db.create(schemas_1.OFCOOP_TABLES.shuConfigs, config);
239
+ }
240
+ async getActive(scope) {
241
+ const now = nowIso();
242
+ const rows = await this.list(scope);
243
+ return rows
244
+ .filter((row) => isEffectiveOn(row.effectiveDate, now))
245
+ .sort((a, b) => b.effectiveDate.localeCompare(a.effectiveDate))[0] ?? null;
246
+ }
247
+ async list(scope, options) {
248
+ const filters = [
249
+ { koperasiId: scope.koperasiId },
250
+ { tenantId: scope.tenantId },
251
+ { branchId: scope.branchId ?? null },
252
+ ];
253
+ if (!options?.includeDeleted)
254
+ filters.push({ deleted: false });
255
+ return this.db.query(schemas_1.OFCOOP_TABLES.shuConfigs, {
256
+ filters: toAnd(filters),
257
+ sort: [{ field: 'effectiveDate', direction: 'desc' }],
258
+ });
259
+ }
260
+ }
261
+ exports.ShuConfigRepository = ShuConfigRepository;
262
+ class ShuPeriodRepository {
263
+ constructor(db) {
264
+ this.db = db;
265
+ }
266
+ async create(period) {
267
+ return this.db.create(schemas_1.OFCOOP_TABLES.shuPeriods, period);
268
+ }
269
+ async update(id, updates) {
270
+ return this.db.update(schemas_1.OFCOOP_TABLES.shuPeriods, id, updates);
271
+ }
272
+ async getById(id) {
273
+ return this.db.get(schemas_1.OFCOOP_TABLES.shuPeriods, id);
274
+ }
275
+ async list(options) {
276
+ const filters = [];
277
+ if (!options?.includeDeleted)
278
+ filters.push({ deleted: false });
279
+ if (options?.tenantId !== undefined)
280
+ filters.push({ tenantId: options.tenantId ?? null });
281
+ if (options?.branchId !== undefined)
282
+ filters.push({ branchId: options.branchId ?? null });
283
+ return this.db.query(schemas_1.OFCOOP_TABLES.shuPeriods, {
284
+ filters: toAnd(filters),
285
+ sort: [{ field: 'lastModified', direction: 'desc' }],
286
+ });
287
+ }
288
+ }
289
+ exports.ShuPeriodRepository = ShuPeriodRepository;
290
+ class ShuAllocationRepository {
291
+ constructor(db) {
292
+ this.db = db;
293
+ }
294
+ async createMany(rows) {
295
+ if (rows.length === 0)
296
+ return [];
297
+ return this.db.bulkCreate(schemas_1.OFCOOP_TABLES.shuAllocations, rows);
298
+ }
299
+ async listByPeriod(periodId, options) {
300
+ const filters = [{ shuPeriodId: periodId }];
301
+ if (!options?.includeDeleted)
302
+ filters.push({ deleted: false });
303
+ if (options?.memberId)
304
+ filters.push({ memberId: options.memberId });
305
+ return this.db.query(schemas_1.OFCOOP_TABLES.shuAllocations, {
306
+ filters: toAnd(filters),
307
+ sort: [{ field: 'lastModified', direction: 'desc' }],
308
+ });
309
+ }
310
+ }
311
+ exports.ShuAllocationRepository = ShuAllocationRepository;
312
+ function createOfcoopRepositories(db) {
313
+ return {
314
+ memberRepository: new MemberRepository(db),
315
+ memberWaConsentRepository: new MemberWaConsentRepository(db),
316
+ memberExitStateRepository: new MemberExitStateRepository(db),
317
+ memberNumberPolicyRepository: new MemberNumberPolicyRepository(db),
318
+ savingPolicyRepository: new SavingPolicyRepository(db),
319
+ savingLedgerRepository: new SavingLedgerRepository(db),
320
+ shuConfigRepository: new ShuConfigRepository(db),
321
+ shuPeriodRepository: new ShuPeriodRepository(db),
322
+ shuAllocationRepository: new ShuAllocationRepository(db),
323
+ };
324
+ }
@@ -0,0 +1,14 @@
1
+ import type { DbSchema, TableSchema } from 'ofcore';
2
+ export declare const OFCOOP_TABLES: {
3
+ readonly members: "ofcoop_members";
4
+ readonly memberWaConsent: "ofcoop_member_wa_consent";
5
+ readonly memberExitState: "ofcoop_member_exit_state";
6
+ readonly memberNumberPolicies: "ofcoop_member_number_policies";
7
+ readonly savingPolicies: "ofcoop_saving_policies";
8
+ readonly savingEntries: "ofcoop_saving_entries";
9
+ readonly shuConfigs: "ofcoop_shu_configs";
10
+ readonly shuPeriods: "ofcoop_shu_periods";
11
+ readonly shuAllocations: "ofcoop_shu_allocations";
12
+ };
13
+ export declare const ofcoopSchema: DbSchema;
14
+ export declare function getOfcoopTableSchemas(): TableSchema[];