feat: deploy infrastructure + disk/drive, calendar, presentation, workspaces, onboarding, demo user

This commit is contained in:
2026-05-19 16:26:26 +03:00
parent 688d043dad
commit 3529c39b22
304 changed files with 18826 additions and 1176 deletions
+134
View File
@@ -0,0 +1,134 @@
class AgentConfig {
final String name;
final String description;
final bool isActive;
final String schedule;
final Map<String, dynamic> config;
AgentConfig({
required this.name,
this.description = '',
this.isActive = true,
this.schedule = '',
this.config = const {},
});
factory AgentConfig.fromJson(Map<String, dynamic> json) => AgentConfig(
name: json['name'] as String? ?? '',
description: json['description'] as String? ?? '',
isActive: json['is_active'] as bool? ?? true,
schedule: json['schedule'] as String? ?? '',
config: json['config'] as Map<String, dynamic>? ?? {},
);
}
class AgentRunResult {
final String agent;
final String status;
final String? message;
AgentRunResult({
required this.agent,
required this.status,
this.message,
});
factory AgentRunResult.fromJson(Map<String, dynamic> json) => AgentRunResult(
agent: json['agent'] as String? ?? '',
status: json['status'] as String? ?? 'error',
message: json['message'] as String?,
);
}
class BotCommand {
final String id;
final String command;
final String description;
final bool isEnabled;
BotCommand({
required this.id,
required this.command,
this.description = '',
this.isEnabled = true,
});
factory BotCommand.fromJson(Map<String, dynamic> json) => BotCommand(
id: json['id'] as String,
command: json['command'] as String,
description: json['description'] as String? ?? '',
isEnabled: json['is_enabled'] as bool? ?? true,
);
}
class LogEntry {
final String id;
final String level;
final String message;
final String? source;
final DateTime createdAt;
LogEntry({
required this.id,
required this.level,
required this.message,
this.source,
required this.createdAt,
});
factory LogEntry.fromJson(Map<String, dynamic> json) => LogEntry(
id: json['id'] as String,
level: json['level'] as String? ?? 'INFO',
message: json['message'] as String,
source: json['source'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
);
}
class AdminStats {
final int totalUsers;
final int totalIdeas;
final int totalVoiceSessions;
final int totalWorkspaces;
final int activeAgents;
final int totalNotifications;
AdminStats({
this.totalUsers = 0,
this.totalIdeas = 0,
this.totalVoiceSessions = 0,
this.totalWorkspaces = 0,
this.activeAgents = 0,
this.totalNotifications = 0,
});
factory AdminStats.fromJson(Map<String, dynamic> json) => AdminStats(
totalUsers: json['total_users'] as int? ?? 0,
totalIdeas: json['total_ideas'] as int? ?? 0,
totalVoiceSessions: json['total_voice_sessions'] as int? ?? 0,
totalWorkspaces: json['total_workspaces'] as int? ?? 0,
activeAgents: json['active_agents'] as int? ?? 0,
totalNotifications: json['total_notifications'] as int? ?? 0,
);
}
class HealthStatus {
final String status;
final String version;
final double uptimeSeconds;
final Map<String, dynamic> services;
HealthStatus({
this.status = 'ok',
this.version = '',
this.uptimeSeconds = 0,
this.services = const {},
});
factory HealthStatus.fromJson(Map<String, dynamic> json) => HealthStatus(
status: json['status'] as String? ?? 'ok',
version: json['version'] as String? ?? '',
uptimeSeconds: (json['uptime_seconds'] as num?)?.toDouble() ?? 0,
services: json['services'] as Map<String, dynamic>? ?? {},
);
}
+119
View File
@@ -0,0 +1,119 @@
class LoginRequest {
final String email;
final String password;
LoginRequest({required this.email, required this.password});
Map<String, dynamic> toJson() => {
'email': email,
'password': password,
};
}
class RegisterRequest {
final String email;
final String password;
final String name;
RegisterRequest({
required this.email,
required this.password,
required this.name,
});
Map<String, dynamic> toJson() => {
'email': email,
'password': password,
'name': name,
};
}
class AuthResponse {
final String accessToken;
final String refreshToken;
final User user;
AuthResponse({
required this.accessToken,
required this.refreshToken,
required this.user,
});
factory AuthResponse.fromJson(Map<String, dynamic> json) => AuthResponse(
accessToken: json['access_token'] as String,
refreshToken: json['refresh_token'] as String,
user: User.fromJson(json['user'] as Map<String, dynamic>),
);
}
class User {
final String id;
final String email;
final String name;
final bool isAdmin;
final bool isTwoFactorEnabled;
final String? tariffId;
final String? calendarProvider;
final DateTime createdAt;
User({
required this.id,
required this.email,
required this.name,
this.isAdmin = false,
this.isTwoFactorEnabled = false,
this.tariffId,
this.calendarProvider,
required this.createdAt,
});
factory User.fromJson(Map<String, dynamic> json) => User(
id: json['id'] as String,
email: json['email'] as String,
name: json['name'] as String? ?? '',
isAdmin: json['is_admin'] as bool? ?? false,
isTwoFactorEnabled: json['is_two_factor_enabled'] as bool? ?? false,
tariffId: json['tariff_id'] as String?,
calendarProvider: json['calendar_provider'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
);
Map<String, dynamic> toJson() => {
'id': id,
'email': email,
'name': name,
'is_admin': isAdmin,
'is_two_factor_enabled': isTwoFactorEnabled,
'tariff_id': tariffId,
'calendar_provider': calendarProvider,
'created_at': createdAt.toIso8601String(),
};
}
class TwoFactorRequest {
final String code;
TwoFactorRequest({required this.code});
Map<String, dynamic> toJson() => {'code': code};
}
class ForgotPasswordRequest {
final String email;
ForgotPasswordRequest({required this.email});
Map<String, dynamic> toJson() => {'email': email};
}
class ResetPasswordRequest {
final String token;
final String password;
ResetPasswordRequest({required this.token, required this.password});
Map<String, dynamic> toJson() => {
'token': token,
'password': password,
};
}
+134
View File
@@ -0,0 +1,134 @@
class Vote {
final String id;
final String ideaId;
final String userId;
final bool isUpvote;
final DateTime createdAt;
Vote({
required this.id,
required this.ideaId,
required this.userId,
required this.isUpvote,
required this.createdAt,
});
factory Vote.fromJson(Map<String, dynamic> json) => Vote(
id: json['id'] as String,
ideaId: json['idea_id'] as String,
userId: json['user_id'] as String,
isUpvote: json['is_upvote'] as bool,
createdAt: DateTime.parse(json['created_at'] as String),
);
}
class Comment {
final String id;
final String ideaId;
final String userId;
final String userName;
final String body;
final String? parentId;
final List<Comment> replies;
final DateTime createdAt;
final DateTime updatedAt;
Comment({
required this.id,
required this.ideaId,
required this.userId,
this.userName = '',
required this.body,
this.parentId,
this.replies = const [],
required this.createdAt,
required this.updatedAt,
});
factory Comment.fromJson(Map<String, dynamic> json) => Comment(
id: json['id'] as String,
ideaId: json['idea_id'] as String,
userId: json['user_id'] as String,
userName: json['user_name'] as String? ?? '',
body: json['body'] as String,
parentId: json['parent_id'] as String?,
replies: (json['replies'] as List<dynamic>? ?? [])
.map((e) => Comment.fromJson(e as Map<String, dynamic>))
.toList(),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
);
}
class CreateCommentRequest {
final String body;
final String? parentId;
CreateCommentRequest({required this.body, this.parentId});
Map<String, dynamic> toJson() => {
'body': body,
if (parentId != null) 'parent_id': parentId,
};
}
class Activity {
final String id;
final String ideaId;
final String userId;
final String userName;
final String action;
final String? description;
final DateTime createdAt;
Activity({
required this.id,
required this.ideaId,
required this.userId,
this.userName = '',
required this.action,
this.description,
required this.createdAt,
});
factory Activity.fromJson(Map<String, dynamic> json) => Activity(
id: json['id'] as String,
ideaId: json['idea_id'] as String,
userId: json['user_id'] as String,
userName: json['user_name'] as String? ?? '',
action: json['action'] as String,
description: json['description'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
);
}
class AppNotification {
final String id;
final String userId;
final String title;
final String body;
final bool isRead;
final String? ideaId;
final DateTime createdAt;
AppNotification({
required this.id,
required this.userId,
required this.title,
required this.body,
this.isRead = false,
this.ideaId,
required this.createdAt,
});
factory AppNotification.fromJson(Map<String, dynamic> json) =>
AppNotification(
id: json['id'] as String,
userId: json['user_id'] as String,
title: json['title'] as String,
body: json['body'] as String? ?? '',
isRead: json['is_read'] as bool? ?? false,
ideaId: json['idea_id'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
);
}
+120
View File
@@ -0,0 +1,120 @@
class Idea {
final String id;
final String title;
final String description;
final String? funnelStatus;
final String? workspaceId;
final String userId;
final String userName;
final int upvotes;
final int downvotes;
final int commentCount;
final DateTime createdAt;
final DateTime updatedAt;
Idea({
required this.id,
required this.title,
required this.description,
this.funnelStatus,
this.workspaceId,
required this.userId,
this.userName = '',
this.upvotes = 0,
this.downvotes = 0,
this.commentCount = 0,
required this.createdAt,
required this.updatedAt,
});
factory Idea.fromJson(Map<String, dynamic> json) => Idea(
id: json['id'] as String,
title: json['title'] as String,
description: json['description'] as String? ?? '',
funnelStatus: json['funnel_status'] as String?,
workspaceId: json['workspace_id'] as String?,
userId: json['user_id'] as String? ?? '',
userName: json['user_name'] as String? ?? '',
upvotes: json['upvotes'] as int? ?? 0,
downvotes: json['downvotes'] as int? ?? 0,
commentCount: json['comment_count'] as int? ?? 0,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
);
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'description': description,
'funnel_status': funnelStatus,
'workspace_id': workspaceId,
'user_id': userId,
'user_name': userName,
'upvotes': upvotes,
'downvotes': downvotes,
'comment_count': commentCount,
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
};
Idea copyWith({
String? title,
String? description,
String? funnelStatus,
int? upvotes,
int? downvotes,
int? commentCount,
}) =>
Idea(
id: id,
title: title ?? this.title,
description: description ?? this.description,
funnelStatus: funnelStatus ?? this.funnelStatus,
workspaceId: workspaceId,
userId: userId,
userName: userName,
upvotes: upvotes ?? this.upvotes,
downvotes: downvotes ?? this.downvotes,
commentCount: commentCount ?? this.commentCount,
createdAt: createdAt,
updatedAt: updatedAt,
);
}
class CreateIdeaRequest {
final String title;
final String description;
final String? workspaceId;
CreateIdeaRequest({
required this.title,
required this.description,
this.workspaceId,
});
Map<String, dynamic> toJson() => {
'title': title,
'description': description,
'workspace_id': workspaceId,
};
}
class UpdateIdeaRequest {
final String? title;
final String? description;
UpdateIdeaRequest({this.title, this.description});
Map<String, dynamic> toJson() => {
if (title != null) 'title': title,
if (description != null) 'description': description,
};
}
class FunnelTransitionRequest {
final String status;
FunnelTransitionRequest({required this.status});
Map<String, dynamic> toJson() => {'status': status};
}
+39
View File
@@ -0,0 +1,39 @@
class Tariff {
final String id;
final String name;
final double price;
final String currency;
final Map<String, dynamic> features;
final bool isActive;
final DateTime createdAt;
Tariff({
required this.id,
required this.name,
required this.price,
this.currency = 'RUB',
required this.features,
this.isActive = true,
required this.createdAt,
});
factory Tariff.fromJson(Map<String, dynamic> json) => Tariff(
id: json['id'] as String,
name: json['name'] as String,
price: (json['price'] as num).toDouble(),
currency: json['currency'] as String? ?? 'RUB',
features: json['features'] as Map<String, dynamic>? ?? {},
isActive: json['is_active'] as bool? ?? true,
createdAt: DateTime.parse(json['created_at'] as String),
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'price': price,
'currency': currency,
'features': features,
'is_active': isActive,
'created_at': createdAt.toIso8601String(),
};
}
+78
View File
@@ -0,0 +1,78 @@
class VoiceSession {
final String id;
final String userId;
final String? title;
final String status;
final int messageCount;
final DateTime createdAt;
final DateTime updatedAt;
VoiceSession({
required this.id,
required this.userId,
this.title,
required this.status,
this.messageCount = 0,
required this.createdAt,
required this.updatedAt,
});
factory VoiceSession.fromJson(Map<String, dynamic> json) => VoiceSession(
id: json['id'] as String,
userId: json['user_id'] as String,
title: json['title'] as String?,
status: json['status'] as String? ?? 'active',
messageCount: json['message_count'] as int? ?? 0,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
);
}
class VoiceCommand {
final String id;
final String sessionId;
final String command;
final String? result;
final DateTime createdAt;
VoiceCommand({
required this.id,
required this.sessionId,
required this.command,
this.result,
required this.createdAt,
});
factory VoiceCommand.fromJson(Map<String, dynamic> json) => VoiceCommand(
id: json['id'] as String,
sessionId: json['session_id'] as String,
command: json['command'] as String,
result: json['result'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
);
}
class TranscribeRequest {
final String audioBase64;
final String? sessionId;
TranscribeRequest({required this.audioBase64, this.sessionId});
Map<String, dynamic> toJson() => {
'audio_base64': audioBase64,
if (sessionId != null) 'session_id': sessionId,
};
}
class TranscribeResponse {
final String text;
final String? sessionId;
TranscribeResponse({required this.text, this.sessionId});
factory TranscribeResponse.fromJson(Map<String, dynamic> json) =>
TranscribeResponse(
text: json['text'] as String,
sessionId: json['session_id'] as String?,
);
}
+84
View File
@@ -0,0 +1,84 @@
class Workspace {
final String id;
final String name;
final String type;
final String? description;
final String ownerId;
final int memberCount;
final DateTime createdAt;
Workspace({
required this.id,
required this.name,
required this.type,
this.description,
required this.ownerId,
this.memberCount = 0,
required this.createdAt,
});
factory Workspace.fromJson(Map<String, dynamic> json) => Workspace(
id: json['id'] as String,
name: json['name'] as String,
type: json['type'] as String? ?? 'personal',
description: json['description'] as String?,
ownerId: json['owner_id'] as String? ?? '',
memberCount: json['member_count'] as int? ?? 0,
createdAt: DateTime.parse(json['created_at'] as String),
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'type': type,
'description': description,
'owner_id': ownerId,
'member_count': memberCount,
'created_at': createdAt.toIso8601String(),
};
bool get isPersonal => type == 'personal';
bool get isTeam => type == 'team';
}
class WorkspaceMember {
final String id;
final String userId;
final String userName;
final String userEmail;
final String role;
final DateTime joinedAt;
WorkspaceMember({
required this.id,
required this.userId,
this.userName = '',
this.userEmail = '',
required this.role,
required this.joinedAt,
});
factory WorkspaceMember.fromJson(Map<String, dynamic> json) =>
WorkspaceMember(
id: json['id'] as String,
userId: json['user_id'] as String? ?? '',
userName: json['user_name'] as String? ?? '',
userEmail: json['user_email'] as String? ?? '',
role: json['role'] as String? ?? 'member',
joinedAt: json['created_at'] != null
? DateTime.parse(json['created_at'] as String)
: DateTime.now(),
);
}
class CreateWorkspaceRequest {
final String name;
final String? description;
CreateWorkspaceRequest({required this.name, this.description});
Map<String, dynamic> toJson() => {
'name': name,
'description': description,
};
}