feat(miniapp): add admin billing settings foundation

This commit is contained in:
2026-03-10 01:38:03 +04:00
parent 4797e4f200
commit 565ac277c1
26 changed files with 5061 additions and 11 deletions

View File

@@ -102,11 +102,131 @@ function repository(): HouseholdConfigurationRepository {
householdDefaultLocale: 'ru',
isAdmin: false
}
: null,
getHouseholdBillingSettings: async (householdId) => ({
householdId,
rentAmountMinor: null,
rentCurrency: 'USD',
rentDueDay: 20,
rentWarningDay: 17,
utilitiesDueDay: 4,
utilitiesReminderDay: 3,
timezone: 'Asia/Tbilisi'
}),
updateHouseholdBillingSettings: async (input) => ({
householdId: input.householdId,
rentAmountMinor: input.rentAmountMinor ?? null,
rentCurrency: input.rentCurrency ?? 'USD',
rentDueDay: input.rentDueDay ?? 20,
rentWarningDay: input.rentWarningDay ?? 17,
utilitiesDueDay: input.utilitiesDueDay ?? 4,
utilitiesReminderDay: input.utilitiesReminderDay ?? 3,
timezone: input.timezone ?? 'Asia/Tbilisi'
}),
listHouseholdUtilityCategories: async () => [],
upsertHouseholdUtilityCategory: async (input) => ({
id: input.slug ?? 'utility-category-1',
householdId: input.householdId,
slug: input.slug ?? 'custom',
name: input.name,
sortOrder: input.sortOrder,
isActive: input.isActive
}),
promoteHouseholdAdmin: async (householdId, memberId) =>
memberId === 'member-123456'
? {
id: memberId,
householdId,
telegramUserId: '123456',
displayName: 'Stan',
preferredLocale: null,
householdDefaultLocale: 'ru',
isAdmin: true
}
: null
}
}
describe('createMiniAppAdminService', () => {
test('returns billing settings, utility categories, and members for admins', async () => {
const service = createMiniAppAdminService(repository())
const result = await service.getSettings({
householdId: 'household-1',
actorIsAdmin: true
})
expect(result).toEqual({
status: 'ok',
settings: {
householdId: 'household-1',
rentAmountMinor: null,
rentCurrency: 'USD',
rentDueDay: 20,
rentWarningDay: 17,
utilitiesDueDay: 4,
utilitiesReminderDay: 3,
timezone: 'Asia/Tbilisi'
},
categories: [],
members: []
})
})
test('updates billing settings for admins', async () => {
const service = createMiniAppAdminService(repository())
const result = await service.updateSettings({
householdId: 'household-1',
actorIsAdmin: true,
rentAmountMajor: '700',
rentCurrency: 'USD',
rentDueDay: 21,
rentWarningDay: 18,
utilitiesDueDay: 5,
utilitiesReminderDay: 4,
timezone: 'Asia/Tbilisi'
})
expect(result).toEqual({
status: 'ok',
settings: {
householdId: 'household-1',
rentAmountMinor: 70000n,
rentCurrency: 'USD',
rentDueDay: 21,
rentWarningDay: 18,
utilitiesDueDay: 5,
utilitiesReminderDay: 4,
timezone: 'Asia/Tbilisi'
}
})
})
test('upserts utility categories for admins', async () => {
const service = createMiniAppAdminService(repository())
const result = await service.upsertUtilityCategory({
householdId: 'household-1',
actorIsAdmin: true,
name: 'Internet',
sortOrder: 0,
isActive: true
})
expect(result).toEqual({
status: 'ok',
category: {
id: 'utility-category-1',
householdId: 'household-1',
slug: 'custom',
name: 'Internet',
sortOrder: 0,
isActive: true
}
})
})
test('lists pending members for admins', async () => {
const service = createMiniAppAdminService(repository())
@@ -167,4 +287,27 @@ describe('createMiniAppAdminService', () => {
}
})
})
test('promotes an active member to household admin', async () => {
const service = createMiniAppAdminService(repository())
const result = await service.promoteMemberToAdmin({
householdId: 'household-1',
actorIsAdmin: true,
memberId: 'member-123456'
})
expect(result).toEqual({
status: 'ok',
member: {
id: 'member-123456',
householdId: 'household-1',
telegramUserId: '123456',
displayName: 'Stan',
preferredLocale: null,
householdDefaultLocale: 'ru',
isAdmin: true
}
})
})
})