Add pricing entry flow and platform admin foundations

This commit is contained in:
egecankomur
2026-06-20 18:24:40 +03:00
parent 1d36ccdf30
commit ac42681f7e
44 changed files with 6567 additions and 1419 deletions
@@ -0,0 +1,142 @@
import 'package:pocketbase/pocketbase.dart';
import '../../core/api/pocketbase_client.dart';
import '../../models/platform_admin.dart';
import '../../models/tenant.dart';
import '../../models/user_profile.dart';
class SuperAdminRepository {
SuperAdminRepository._();
static final instance = SuperAdminRepository._();
PocketBase get _pb => PocketBaseClient.instance.pb;
Future<List<PlatformMembership>> listPlatformMemberships() async {
final result = await _pb.collection('platform_memberships').getList(
perPage: 100,
sort: '-created',
);
return result.items
.map((record) => PlatformMembership.fromJson(record.toJson()))
.toList();
}
Future<List<TenantSubscription>> listSubscriptions() async {
final result = await _pb.collection('tenant_subscriptions').getList(
perPage: 200,
sort: '-updated',
);
return result.items
.map((record) => TenantSubscription.fromJson(record.toJson()))
.toList();
}
Future<List<AiCreditLedgerEntry>> listCreditLedger(
String tenantId, {
int limit = 200,
}) async {
final result = await _pb.collection('ai_credit_ledger').getList(
perPage: limit,
sort: '-created',
filter: 'tenant_id = "$tenantId"',
);
return result.items
.map((record) => AiCreditLedgerEntry.fromJson(record.toJson()))
.toList();
}
Future<List<AiUsageLog>> listAiUsage({
String? tenantId,
int limit = 200,
}) async {
final result = await _pb.collection('ai_usage_logs').getList(
perPage: limit,
sort: '-created',
filter: tenantId != null ? 'tenant_id = "$tenantId"' : '',
);
return result.items
.map((record) => AiUsageLog.fromJson(record.toJson()))
.toList();
}
Future<List<AdminAuditLog>> listAuditLogs({int limit = 200}) async {
final result = await _pb.collection('admin_audit_logs').getList(
perPage: limit,
sort: '-created',
);
return result.items
.map((record) => AdminAuditLog.fromJson(record.toJson()))
.toList();
}
Future<void> assignPlatformRole({
required String userId,
required PlatformRole role,
String status = 'active',
}) async {
final existing = await _pb.collection('platform_memberships').getList(
perPage: 1,
filter: 'user_id = "$userId"',
);
if (existing.items.isEmpty) {
await _pb.collection('platform_memberships').create(body: {
'user_id': userId,
'role': role.value,
'status': status,
});
return;
}
await _pb.collection('platform_memberships').update(
existing.items.first.id,
body: {
'role': role.value,
'status': status,
},
);
}
Future<void> upsertSubscription({
required String tenantId,
required TenantPlan plan,
required SubscriptionStatus status,
String? billingProvider,
int? aiMonthlyCredits,
int? aiBonusCredits,
}) async {
final existing = await _pb.collection('tenant_subscriptions').getList(
perPage: 1,
filter: 'tenant_id = "$tenantId"',
);
final body = <String, dynamic>{
'tenant_id': tenantId,
'plan': plan.name,
'status': status.value,
if (billingProvider != null) 'billing_provider': billingProvider,
if (aiMonthlyCredits != null) 'ai_monthly_credits': aiMonthlyCredits,
if (aiBonusCredits != null) 'ai_bonus_credits': aiBonusCredits,
};
if (existing.items.isEmpty) {
await _pb.collection('tenant_subscriptions').create(body: body);
return;
}
await _pb.collection('tenant_subscriptions').update(
existing.items.first.id,
body: body,
);
}
}
class SuperAdminDashboardSnapshot {
const SuperAdminDashboardSnapshot({
required this.platformUsers,
required this.tenants,
required this.activeSubscriptions,
required this.aiUsageLogs,
});
final List<UserProfile> platformUsers;
final List<Tenant> tenants;
final List<TenantSubscription> activeSubscriptions;
final List<AiUsageLog> aiUsageLogs;
}