halkyon/halkyon_learn_client/lib/src/protocol/discussion/discussion_target.dart

106 lines
2.7 KiB
Dart
Raw Normal View History

feat(discussions): questions on published studysets, answered by learners A learner asks about a published studyset, a topic in it, or one card, note or step of a release, and others answer, as on Stack Exchange (ADR 0013): questions and answers in the app's editor without images, sounds or videos, comments of up to 600 characters under the question and each answer. There are no votes: the asker accepts an answer, which comes first, then the oldest; the author's posts are marked. The instance reads from git's file list which topics a question's target sits in, so a topic lists what is asked within it and below it. Posts live in two server-only tables, written through endpoints, so the synced tables stay as they are and v0.17.0 keeps syncing. Everyone signed in reads; writing needs an identity and a public profile; the studyset's author hides posts and blocks people with feedback's blocks; a withdrawn studyset takes no new questions; anyone writes at most 30 posts an hour. A post with others' replies under it is emptied when deleted, else deleted; deletePerson deletes what a person wrote the same way, and a published studyset's deletion takes its discussions with it. The migration adds Serverpod's gen_random_uuid_v7(), discussion_post and discussion_seen with their indexes and cascading foreign keys, and changes nothing else. In the app, discussions open from a copy's studyset or topic menu, a studied card's "Ask about this", Explore's summary and the Publish sheet; the Profile tab's inbox lists those the person follows, and its count includes what is new in them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-15 23:52:40 +02:00
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
/* To generate run: "serverpod generate" */
// ignore_for_file: implementation_imports
// ignore_for_file: library_private_types_in_public_api
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: public_member_api_docs
// ignore_for_file: type_literal_in_constant_pattern
// ignore_for_file: use_super_parameters
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:serverpod_client/serverpod_client.dart' as _isc;
/// What a question is about: the published studyset or a topic in it
/// ('studyset'), or one of its cards, notes or steps ('card', 'note',
/// 'step'), by its id in release [version].
abstract class DiscussionTarget
implements _isc.SerializableModel, _isc.ProtocolSerialization {
DiscussionTarget._({
required this.kind,
required this.item,
required this.version,
});
factory DiscussionTarget({
required String kind,
required String item,
required int version,
}) = _DiscussionTargetImpl;
factory DiscussionTarget.fromJson(Map<String, dynamic> jsonSerialization) {
return DiscussionTarget(
kind: jsonSerialization['kind'] as String,
item: jsonSerialization['item'] as String,
version: jsonSerialization['version'] as int,
);
}
String kind;
String item;
int version;
/// Returns a shallow copy of this [DiscussionTarget]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
DiscussionTarget copyWith({
String? kind,
String? item,
int? version,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'DiscussionTarget',
'kind': kind,
'item': item,
'version': version,
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'DiscussionTarget',
'kind': kind,
'item': item,
'version': version,
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _DiscussionTargetImpl extends DiscussionTarget {
_DiscussionTargetImpl({
required String kind,
required String item,
required int version,
}) : super._(
kind: kind,
item: item,
version: version,
);
/// Returns a shallow copy of this [DiscussionTarget]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
DiscussionTarget copyWith({
String? kind,
String? item,
int? version,
}) {
return DiscussionTarget(
kind: kind ?? this.kind,
item: item ?? this.item,
version: version ?? this.version,
);
}
}