299 lines
9.0 KiB
Dart
299 lines
9.0 KiB
Dart
import 'tenant.dart';
|
|
|
|
enum PlatformRole {
|
|
superAdmin,
|
|
support,
|
|
financeOps,
|
|
operations,
|
|
readOnly,
|
|
;
|
|
|
|
String get value => switch (this) {
|
|
PlatformRole.superAdmin => 'super_admin',
|
|
PlatformRole.support => 'support',
|
|
PlatformRole.financeOps => 'finance_ops',
|
|
PlatformRole.operations => 'operations',
|
|
PlatformRole.readOnly => 'read_only',
|
|
};
|
|
|
|
String get label => switch (this) {
|
|
PlatformRole.superAdmin => 'Super Admin',
|
|
PlatformRole.support => 'Destek',
|
|
PlatformRole.financeOps => 'Finans Operasyon',
|
|
PlatformRole.operations => 'Operasyon',
|
|
PlatformRole.readOnly => 'Sadece Görüntüleme',
|
|
};
|
|
|
|
static PlatformRole parse(String raw) => switch (raw) {
|
|
'super_admin' => PlatformRole.superAdmin,
|
|
'support' => PlatformRole.support,
|
|
'finance_ops' => PlatformRole.financeOps,
|
|
'operations' => PlatformRole.operations,
|
|
'read_only' => PlatformRole.readOnly,
|
|
_ => PlatformRole.readOnly,
|
|
};
|
|
}
|
|
|
|
class PlatformMembership {
|
|
const PlatformMembership({
|
|
required this.id,
|
|
required this.userId,
|
|
required this.role,
|
|
this.status = 'active',
|
|
});
|
|
|
|
final String id;
|
|
final String userId;
|
|
final PlatformRole role;
|
|
final String status;
|
|
|
|
bool get isActive => status == 'active';
|
|
bool get isSuperAdmin => role == PlatformRole.superAdmin && isActive;
|
|
bool get canManageBilling =>
|
|
isActive &&
|
|
(role == PlatformRole.superAdmin || role == PlatformRole.financeOps);
|
|
bool get canManageTenants =>
|
|
isActive &&
|
|
(role == PlatformRole.superAdmin ||
|
|
role == PlatformRole.operations ||
|
|
role == PlatformRole.support);
|
|
|
|
factory PlatformMembership.fromJson(Map<String, dynamic> json) {
|
|
return PlatformMembership(
|
|
id: json['id'] as String,
|
|
userId: json['user_id'] as String,
|
|
role: PlatformRole.parse(json['role'] as String? ?? ''),
|
|
status: (json['status'] as String?) ?? 'active',
|
|
);
|
|
}
|
|
}
|
|
|
|
enum SubscriptionStatus { trialing, active, pastDue, cancelled, paused }
|
|
|
|
extension SubscriptionStatusX on SubscriptionStatus {
|
|
String get value => switch (this) {
|
|
SubscriptionStatus.trialing => 'trialing',
|
|
SubscriptionStatus.active => 'active',
|
|
SubscriptionStatus.pastDue => 'past_due',
|
|
SubscriptionStatus.cancelled => 'cancelled',
|
|
SubscriptionStatus.paused => 'paused',
|
|
};
|
|
|
|
static SubscriptionStatus parse(String raw) => switch (raw) {
|
|
'trialing' => SubscriptionStatus.trialing,
|
|
'active' => SubscriptionStatus.active,
|
|
'past_due' => SubscriptionStatus.pastDue,
|
|
'cancelled' => SubscriptionStatus.cancelled,
|
|
'paused' => SubscriptionStatus.paused,
|
|
_ => SubscriptionStatus.trialing,
|
|
};
|
|
}
|
|
|
|
class TenantSubscription {
|
|
const TenantSubscription({
|
|
required this.id,
|
|
required this.tenantId,
|
|
required this.plan,
|
|
required this.status,
|
|
this.billingProvider,
|
|
this.providerCustomerId,
|
|
this.providerSubscriptionId,
|
|
this.periodStart,
|
|
this.periodEnd,
|
|
this.aiMonthlyCredits = 0,
|
|
this.aiBonusCredits = 0,
|
|
});
|
|
|
|
final String id;
|
|
final String tenantId;
|
|
final TenantPlan plan;
|
|
final SubscriptionStatus status;
|
|
final String? billingProvider;
|
|
final String? providerCustomerId;
|
|
final String? providerSubscriptionId;
|
|
final DateTime? periodStart;
|
|
final DateTime? periodEnd;
|
|
final int aiMonthlyCredits;
|
|
final int aiBonusCredits;
|
|
|
|
int get totalAiCredits => aiMonthlyCredits + aiBonusCredits;
|
|
|
|
factory TenantSubscription.fromJson(Map<String, dynamic> json) {
|
|
return TenantSubscription(
|
|
id: json['id'] as String,
|
|
tenantId: json['tenant_id'] as String,
|
|
plan: Tenant.parsePlanValue(json['plan'] as String?),
|
|
status: SubscriptionStatusX.parse(json['status'] as String? ?? ''),
|
|
billingProvider: json['billing_provider'] as String?,
|
|
providerCustomerId: json['provider_customer_id'] as String?,
|
|
providerSubscriptionId: json['provider_subscription_id'] as String?,
|
|
periodStart: _parseDate(json['period_start']),
|
|
periodEnd: _parseDate(json['period_end']),
|
|
aiMonthlyCredits: (json['ai_monthly_credits'] as num?)?.toInt() ?? 0,
|
|
aiBonusCredits: (json['ai_bonus_credits'] as num?)?.toInt() ?? 0,
|
|
);
|
|
}
|
|
}
|
|
|
|
enum AiCreditEntryType {
|
|
monthlyAllocation,
|
|
bonusAllocation,
|
|
usageDebit,
|
|
manualAdjustment,
|
|
refund,
|
|
expire,
|
|
;
|
|
|
|
String get value => switch (this) {
|
|
AiCreditEntryType.monthlyAllocation => 'monthly_allocation',
|
|
AiCreditEntryType.bonusAllocation => 'bonus_allocation',
|
|
AiCreditEntryType.usageDebit => 'usage_debit',
|
|
AiCreditEntryType.manualAdjustment => 'manual_adjustment',
|
|
AiCreditEntryType.refund => 'refund',
|
|
AiCreditEntryType.expire => 'expire',
|
|
};
|
|
|
|
static AiCreditEntryType parse(String raw) => switch (raw) {
|
|
'monthly_allocation' => AiCreditEntryType.monthlyAllocation,
|
|
'bonus_allocation' => AiCreditEntryType.bonusAllocation,
|
|
'usage_debit' => AiCreditEntryType.usageDebit,
|
|
'manual_adjustment' => AiCreditEntryType.manualAdjustment,
|
|
'refund' => AiCreditEntryType.refund,
|
|
'expire' => AiCreditEntryType.expire,
|
|
_ => AiCreditEntryType.manualAdjustment,
|
|
};
|
|
}
|
|
|
|
class AiCreditLedgerEntry {
|
|
const AiCreditLedgerEntry({
|
|
required this.id,
|
|
required this.tenantId,
|
|
required this.entryType,
|
|
required this.delta,
|
|
required this.balanceAfter,
|
|
this.referenceType,
|
|
this.referenceId,
|
|
this.note,
|
|
this.createdByUserId,
|
|
this.createdAt,
|
|
});
|
|
|
|
final String id;
|
|
final String tenantId;
|
|
final AiCreditEntryType entryType;
|
|
final int delta;
|
|
final int balanceAfter;
|
|
final String? referenceType;
|
|
final String? referenceId;
|
|
final String? note;
|
|
final String? createdByUserId;
|
|
final DateTime? createdAt;
|
|
|
|
factory AiCreditLedgerEntry.fromJson(Map<String, dynamic> json) {
|
|
return AiCreditLedgerEntry(
|
|
id: json['id'] as String,
|
|
tenantId: json['tenant_id'] as String,
|
|
entryType: AiCreditEntryType.parse(json['entry_type'] as String? ?? ''),
|
|
delta: (json['delta'] as num?)?.toInt() ?? 0,
|
|
balanceAfter: (json['balance_after'] as num?)?.toInt() ?? 0,
|
|
referenceType: json['reference_type'] as String?,
|
|
referenceId: json['reference_id'] as String?,
|
|
note: json['note'] as String?,
|
|
createdByUserId: json['created_by_user_id'] as String?,
|
|
createdAt: _parseDate(json['created']),
|
|
);
|
|
}
|
|
}
|
|
|
|
class AiUsageLog {
|
|
const AiUsageLog({
|
|
required this.id,
|
|
required this.tenantId,
|
|
required this.userId,
|
|
required this.action,
|
|
required this.creditCost,
|
|
this.model,
|
|
this.jobId,
|
|
this.tokenInput,
|
|
this.tokenOutput,
|
|
this.latencyMs,
|
|
this.createdAt,
|
|
});
|
|
|
|
final String id;
|
|
final String tenantId;
|
|
final String userId;
|
|
final String action;
|
|
final int creditCost;
|
|
final String? model;
|
|
final String? jobId;
|
|
final int? tokenInput;
|
|
final int? tokenOutput;
|
|
final int? latencyMs;
|
|
final DateTime? createdAt;
|
|
|
|
factory AiUsageLog.fromJson(Map<String, dynamic> json) {
|
|
return AiUsageLog(
|
|
id: json['id'] as String,
|
|
tenantId: json['tenant_id'] as String,
|
|
userId: json['user_id'] as String,
|
|
action: json['action'] as String? ?? '',
|
|
creditCost: (json['credit_cost'] as num?)?.toInt() ?? 0,
|
|
model: json['model'] as String?,
|
|
jobId: json['job_id'] as String?,
|
|
tokenInput: (json['token_input'] as num?)?.toInt(),
|
|
tokenOutput: (json['token_output'] as num?)?.toInt(),
|
|
latencyMs: (json['latency_ms'] as num?)?.toInt(),
|
|
createdAt: _parseDate(json['created']),
|
|
);
|
|
}
|
|
}
|
|
|
|
class AdminAuditLog {
|
|
const AdminAuditLog({
|
|
required this.id,
|
|
required this.actorUserId,
|
|
required this.actorRole,
|
|
required this.actionType,
|
|
this.targetCollection,
|
|
this.targetRecordId,
|
|
this.targetTenantId,
|
|
this.summary,
|
|
this.metadata,
|
|
this.createdAt,
|
|
});
|
|
|
|
final String id;
|
|
final String actorUserId;
|
|
final PlatformRole actorRole;
|
|
final String actionType;
|
|
final String? targetCollection;
|
|
final String? targetRecordId;
|
|
final String? targetTenantId;
|
|
final String? summary;
|
|
final Map<String, dynamic>? metadata;
|
|
final DateTime? createdAt;
|
|
|
|
factory AdminAuditLog.fromJson(Map<String, dynamic> json) {
|
|
final metadata = json['metadata'];
|
|
return AdminAuditLog(
|
|
id: json['id'] as String,
|
|
actorUserId: json['actor_user_id'] as String,
|
|
actorRole: PlatformRole.parse(json['actor_role'] as String? ?? ''),
|
|
actionType: json['action_type'] as String? ?? '',
|
|
targetCollection: json['target_collection'] as String?,
|
|
targetRecordId: json['target_record_id'] as String?,
|
|
targetTenantId: json['target_tenant_id'] as String?,
|
|
summary: json['summary'] as String?,
|
|
metadata: metadata is Map<String, dynamic> ? metadata : null,
|
|
createdAt: _parseDate(json['created']),
|
|
);
|
|
}
|
|
}
|
|
|
|
DateTime? _parseDate(dynamic raw) {
|
|
final value = raw as String?;
|
|
if (value == null || value.isEmpty) return null;
|
|
return DateTime.tryParse(value);
|
|
}
|