import 'package:drift/drift.dart'; import 'package:drift_postgres/drift_postgres.dart'; import '../converters.dart' show generateUuid, JsonListConverter, JsonMapConverter, StringListConverter; import 'users.dart'; /// Таблица Tasks - задачи системы class Tasks extends Table { // ID как String, но фактически UUID (генерируется PostgreSQL на стороне БД) TextColumn get id => text().withDefault(const CustomExpression('gen_random_uuid()::text'))(); TextColumn get name => text()(); IntColumn get minCycleMillis => integer()(); IntColumn get maxCycleMillis => integer()(); IntColumn get intervalMillis => integer()(); IntColumn get timeoutMillis => integer()(); TextColumn get status => text().nullable()(); TextColumn get description => text().nullable()(); Column get lastExecution => customType(PgTypes.timestampWithTimezone).nullable()(); // Audit Column get createdAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); Column get updatedAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); @override Set get primaryKey => {id}; } /// Таблица UserTasks - задачи пользователей class UserTasks extends Table { // ID как String, но фактически UUID (генерируется PostgreSQL на стороне БД) TextColumn get id => text().withDefault(const CustomExpression('gen_random_uuid()::text'))(); TextColumn get title => text()(); TextColumn get description => text()(); TextColumn get type => text()(); // app_internal, external, social TextColumn get difficulty => text()(); // easy, medium, hard TextColumn get status => text()(); // available, in_progress, completed, expired, failed // Награды (JSON array) TextColumn get rewards => text().withDefault(const Constant('[]')).map(const JsonListConverter())(); Column get createdAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); Column get expiresAt => customType(PgTypes.timestampWithTimezone)(); Column get completedAt => customType(PgTypes.timestampWithTimezone).nullable()(); TextColumn get proofUrl => text().nullable()(); TextColumn get instructions => text().nullable()(); // Теги (JSON array) TextColumn get tags => text() .withDefault(const Constant('[]')) .map(const StringListConverter())(); TextColumn get imageUrl => text().nullable()(); // Audit Column get updatedAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); @override Set get primaryKey => {id}; } /// Таблица UserTaskProgresses - прогресс выполнения задач пользователями class UserTaskProgresses extends Table { // ID как String, но фактически UUID (генерируется PostgreSQL на стороне БД) TextColumn get id => text().withDefault(const CustomExpression('gen_random_uuid()::text'))(); TextColumn get userId => text().references(Users, #id, onDelete: KeyAction.cascade)(); TextColumn get taskId => text()(); // Reference to UserTasks, but not FK to avoid circular deps // Прогресс (JSON) TextColumn get progress => text().withDefault(const Constant('{}')).map(const JsonMapConverter())(); Column get startedAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); Column get updatedAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); @override Set get primaryKey => {id}; } /// Таблица UserTaskResults - результаты выполнения задач class UserTaskResults extends Table { // ID как String, но фактически UUID (генерируется PostgreSQL на стороне БД) TextColumn get id => text().withDefault(const CustomExpression('gen_random_uuid()::text'))(); TextColumn get userId => text().references(Users, #id, onDelete: KeyAction.cascade)(); TextColumn get taskId => text()(); // Reference to UserTasks // Результаты (JSON) TextColumn get results => text().withDefault(const Constant('{}')).map(const JsonMapConverter())(); Column get completedAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); // Audit Column get createdAt => customType(PgTypes.timestampWithTimezone).withDefault(now())(); @override Set get primaryKey => {id}; } // Конвертеры импортированы из converters.dart