A connect code, an authorization code and a refresh token are each consumed by deleting their row and going on only if that deleted it, so of two requests racing with the same one only one succeeds (as OAuth requires); tests race them. Registration, open to anyone, takes at most 200 clients an hour (429 after), so a flood can't fill the table before pruning. The deploy reloads Caddy in place when deploy/Caddyfile changed, as `docker compose up` doesn't restart it for a file it mounts: without it the connector's paths wouldn't reach the web server. Also formats the app's fake assistant gateway, new and so unchecked by the last commit's check (tool/check.sh formats tracked files only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
53 lines
1.5 KiB
Dart
53 lines
1.5 KiB
Dart
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_gateway.dart';
|
|
import 'package:halkyon_learn_flutter/src/feature/assistant/model/connected_assistant.dart';
|
|
|
|
/// An instance offering the connector at [url] (none when null), with
|
|
/// [initially] connected; [unreachable] makes every call fail as offline.
|
|
class FakeAssistantGateway({
|
|
/// Where the connector is; none when null.
|
|
final String? url = 'https://learn.example.org/mcp',
|
|
|
|
/// The assistants connected at first.
|
|
final List<ConnectedAssistant> initially = const [],
|
|
}) implements AssistantGateway {
|
|
/// Whether the instance can't be reached, failing every call while set.
|
|
bool unreachable = false;
|
|
|
|
/// The assistants connected.
|
|
late final List<ConnectedAssistant> connected = [...initially];
|
|
|
|
/// The codes given out, the last one valid.
|
|
final codes = <String>[];
|
|
|
|
void _reach() {
|
|
if (unreachable) {
|
|
throw Exception('offline');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<String?> connectorUrl() async {
|
|
_reach();
|
|
return url;
|
|
}
|
|
|
|
@override
|
|
Future<ConnectCode> connectCode() async {
|
|
_reach();
|
|
final code = 'K7QX-M2P${codes.length}';
|
|
codes.add(code);
|
|
return (code: code, expiresAt: DateTime.utc(2026, 10, 10, 12, 10));
|
|
}
|
|
|
|
@override
|
|
Future<List<ConnectedAssistant>> connections() async {
|
|
_reach();
|
|
return [...connected];
|
|
}
|
|
|
|
@override
|
|
Future<void> disconnect(int id) async {
|
|
_reach();
|
|
connected.removeWhere((assistant) => assistant.id == id);
|
|
}
|
|
}
|