feat(miniapp): carry overdue billing and admin role flows

This commit is contained in:
2026-03-23 15:44:55 +04:00
parent ee8c53d89b
commit 5af14e101e
44 changed files with 2965 additions and 329 deletions

View File

@@ -173,6 +173,20 @@ export interface MiniAppAdminService {
reason: 'not_admin' | 'member_not_found'
}
>
demoteMemberFromAdmin(input: {
householdId: string
actorIsAdmin: boolean
memberId: string
}): Promise<
| {
status: 'ok'
member: HouseholdMemberRecord
}
| {
status: 'rejected'
reason: 'not_admin' | 'member_not_found' | 'last_admin'
}
>
updateMemberRentShareWeight(input: {
householdId: string
actorIsAdmin: boolean
@@ -649,6 +663,47 @@ export function createMiniAppAdminService(
}
},
async demoteMemberFromAdmin(input) {
if (!input.actorIsAdmin) {
return {
status: 'rejected',
reason: 'not_admin'
}
}
const members = await repository.listHouseholdMembers(input.householdId)
const targetMember = members.find((member) => member.id === input.memberId)
if (!targetMember) {
return {
status: 'rejected',
reason: 'member_not_found'
}
}
const adminCount = members.filter((member) => member.isAdmin).length
if (targetMember.isAdmin && adminCount <= 1) {
return {
status: 'rejected',
reason: 'last_admin'
}
}
const member = targetMember.isAdmin
? await repository.demoteHouseholdAdmin(input.householdId, input.memberId)
: targetMember
if (!member) {
return {
status: 'rejected',
reason: 'member_not_found'
}
}
return {
status: 'ok',
member
}
},
async updateMemberRentShareWeight(input) {
if (!input.actorIsAdmin) {
return {