Skip to main content

tom_core_server 1.3.0 copy "tom_core_server: ^1.3.0" to clipboard
tom_core_server: ^1.3.0 copied to clipboard

Server library for the TOM framework.

example/tom_core_server_example.dart

// ignore_for_file: avoid_print
/// The package's example runner: every module example, in reading order.
///
/// `tom_core_server` has no single introductory program, because it is
/// twenty-five modules and no one program is the way in. What it has instead is
/// a runnable sample per module, and this is the index of them — as a list a
/// reader can read and a runner that executes it:
///
/// ```bash
/// dart run example/tom_core_server_example.dart
/// ```
///
/// from the package root, which is where the paths in [tour] resolve. Each
/// entry is one program with one line saying what it shows; to see only one,
/// run its path directly. The order is the one the README's sample map uses:
/// the server and its endpoints first, then persistence, then the services
/// built on it, then the small modules.
///
/// **A green run is a verification, not a transcript.** Every example states
/// its expectations through `example/_support/check.dart`, which throws when
/// one does not hold, so a program that exits 0 is one whose claims held. This
/// runner reports the exit code of each and fails if any of them did not —
/// which makes the whole set one command.
///
/// Four programs are deliberately left out; [notOnTheTour] names them with the
/// reason. `test/examples_test.dart` requires those two lists together to be
/// exactly the example programs in the package, so a module example added
/// later has to appear here rather than quietly not being on the tour.
library;

import 'dart:io';

import '_support/check.dart';

/// One example program, and what running it shows.
class TourStop {
  /// Creates a stop.
  const TourStop(this.path, this.shows);

  /// The program, relative to the package root.
  final String path;

  /// What a reader learns from its transcript.
  final String shows;
}

/// Every example program this runner runs, in reading order.
const List<TourStop> tour = [
  TourStop(
    'example/server/server_example.dart',
    'The request pipeline: per-request log state, the credential reader and '
        'the outcomes that tell its anonymous answers apart, two middlewares',
  ),
  TourStop(
    'example/server/graceful_shutdown_example.dart',
    'A graceful shutdown step by step: readiness off, new requests refused, '
        'the request and the scheduled run in flight finished, the lease '
        'released',
  ),
  TourStop(
    'example/endpoints/endpoints_example.dart',
    'Declaring routed endpoints, and what the router makes of them',
  ),
  TourStop(
    'example/endpoints/idempotency_example.dart',
    'Idempotency keys: a retried POST runs once and gets the first response',
  ),
  TourStop(
    'example/object_persistence/object_persistence_example.dart',
    'Repositories, the persistence annotations, and the query builder',
  ),
  TourStop(
    'example/object_persistence/optimistic_locking_example.dart',
    'Optimistic locking: the version field, the update it guards, the migration',
  ),
  TourStop(
    'example/object_persistence/entity_lifecycle_example.dart',
    'Soft delete, history tables, lifecycle hooks and change events: the '
        'declarations, the zone that shows deleted rows, the listener '
        'registry and a change as JSON',
  ),
  TourStop(
    'example/object_persistence/subquery_example.dart',
    'Subqueries: a correlated EXISTS, NOT EXISTS and IN (SELECT …) built with '
        'the query builder, and how the enclosing tree sees them',
  ),
  TourStop(
    'example/object_persistence/field_encryption_example.dart',
    'Field-level encryption: ciphertext at rest, the blind-index lookup, '
        'data-key, index-key and key-encryption-key rotation, audit redaction',
  ),
  TourStop(
    'example/datasources/datasources_example.dart',
    'SQL-typed values and how each dialect renders them',
  ),
  TourStop(
    'example/datasources/read_replicas_example.dart',
    'Read replicas: which statements a replica may serve, read-only work, '
        'reads pinned to the primary, and the replica settings',
  ),
  TourStop(
    'example/db_migration/db_migration_example.dart',
    'Versioned schema migrations and the plan a chain produces',
  ),
  TourStop(
    'example/db_migration/db_migration_repair_example.dart',
    'The migration lock\'s name and wait, repairing a failed migration and '
        'rolling migrations back from the command line, and down scripts',
  ),
  TourStop(
    'example/ratelimit/rate_limit_example.dart',
    'Service accounts with scoped API keys, rotation, revocation, rate limits',
  ),
  TourStop(
    'example/tenancy/tenancy_example.dart',
    'Two tenants: resolution, token binding, caches, revocations, jobs, outbox',
  ),
  TourStop(
    'example/transactions/transactions_example.dart',
    'Local and XA transaction coordination',
  ),
  TourStop(
    'example/transactions/saga_example.dart',
    'Sagas: steps run in order, a failed step compensating the ones before it '
        'last first, a failed compensation, and a saga resumed after a restart',
  ),
  TourStop(
    'example/transactions/transaction_recovery_example.dart',
    'Two-phase recovery: the decision recorded before the commit phase and '
        'forgotten after, a decided branch committed and an undecided one '
        'rolled back, and branch ownership and age',
  ),
  TourStop(
    'example/configuration/configuration_example.dart',
    'Typed configuration from arguments, environment and YAML resources',
  ),
  TourStop(
    'example/configuration/secrets_example.dart',
    'Secret references in configuration: precedence, rotation, providers',
  ),
  TourStop(
    'example/cache/cache_example.dart',
    'The isolate-backed cache, its lifetimes, and what "cache forever" means',
  ),
  TourStop(
    'example/authentication/authentication_example.dart',
    'The authentication service contract end to end, without a database',
  ),
  TourStop(
    'example/authentication/oauth_login_example.dart',
    'The OAuth 2.0 / OIDC handshake: signing in through an external provider',
  ),
  TourStop(
    'example/authentication/scim_provisioning_example.dart',
    'SCIM 2.0 provisioning, and deprovisioning that ends the sessions held',
  ),
  TourStop(
    'example/authentication/two_factor_enrolment_example.dart',
    'The first time a policy demands a factor the user has not set up yet',
  ),
  TourStop(
    'example/authentication/two_factor_login_example.dart',
    'The two-pass login a principal that still owes a second factor takes',
  ),
  TourStop(
    'example/authorization/authorization_example.dart',
    'The per-token principal cache, graded grants, resource roles, delegation',
  ),
  TourStop(
    'example/authorization/resource_data_scope_example.dart',
    'The grant-driven row scope those grants filter the database with',
  ),
  TourStop(
    'example/audit/audit_example.dart',
    'Audit records, the declared/automatic split, the hash chain, the trail '
        "schema and its write-once check, and anchors published outside the "
        'server',
  ),
  TourStop(
    'example/privacy/privacy_example.dart',
    'Personal data: the subjects the framework entities declare, a value '
        'sealed under a subject key, the trail sealing it, and the shred that '
        'makes it unreadable while the chain still verifies',
  ),
  TourStop(
    'example/messaging/messaging_example.dart',
    'The outbound substrate without a mail server: composition, the MIME '
        'document, stand-in transports, the durable outbox',
  ),
  TourStop(
    'example/messaging/messaging_templated_example.dart',
    'The application-level half: the templated services, and the SMS channel',
  ),
  TourStop(
    'example/messaging/sms_gateway_presets.dart',
    'Worked field mappings for three named SMS gateways — as an example, not '
        'as library API',
  ),
  TourStop(
    'example/messaging/inbox_example.dart',
    'The idempotent receiver: a message delivered more than once is processed '
        'once, and acknowledged only after it was',
  ),
  TourStop(
    'example/notifications/notifications_example.dart',
    'Notification types and per-user channel choices: one notification fanned '
        'out to the outbox, held through quiet hours, and sent once however '
        'often it is dispatched',
  ),
  TourStop(
    'example/export/export_example.dart',
    'The streaming tabular shape, columns derived from a reflected entity, '
        'the CSV/XLSX/PDF renderers, the format registry and the storage '
        'backends',
  ),
  TourStop(
    'example/export/export_email.dart',
    'A third delivery channel, composed from the module rather than built in',
  ),
  TourStop(
    'example/export/export_retention.dart',
    'Reclaiming what stored exports accumulate, and who owns the enumeration',
  ),
  TourStop(
    'example/resources/resources_example.dart',
    'Localized text as an argument rather than ambient state: bundle sets, '
        'the three-rung fallback chain, and the completeness check',
  ),
  TourStop(
    'example/preferences/preferences_example.dart',
    'The five-piece bootstrap a user preference needs, with a scalar and a '
        'reflected object written and read back',
  ),
  TourStop(
    'example/file_storage/file_storage_example.dart',
    'The one streaming blob contract, the key grammar, the '
        'infrastructure-free backends and the blob-backed export store',
  ),
  TourStop(
    'example/file_storage/deduplicating_store_example.dart',
    'One copy per content, a quota per owner, and the sweep of files no row '
        'refers to',
  ),
  TourStop(
    'example/scheduling/scheduling_example.dart',
    'The relational job queue and lease lock: the schema, why each constraint '
        'is load-bearing, and the UTC instant encoding',
  ),
  TourStop(
    'example/item_authorization/item_authorization_example.dart',
    'Item authorizations kept by an external authority: checks cached until a '
        'change names them, sharing for the user, and the row scope',
  ),
  TourStop(
    'example/metrics/metrics_example.dart',
    'Requests counted by route pattern, the token-guarded Prometheus scrape, '
        'and the same registry pushed over OTLP',
  ),
  TourStop(
    'example/tracing/tracing_example.dart',
    'A request as a server span continuing its caller, its transaction and '
        'outgoing call as children, and the tree exported over OTLP',
  ),
  TourStop(
    'example/healthcheck/healthcheck_example.dart',
    'The health and readiness verdicts, and what a probe can act on',
  ),
  TourStop(
    'example/healthcheck/readiness_logging_example.dart',
    'The framework readiness checks behind /ready, and the JSON log line a '
        'request writes with its trace and request ids',
  ),
  TourStop(
    'example/cmdline/cmdline_example.dart',
    'Reading a command line and an env file into a typed configuration',
  ),
  TourStop(
    'example/little_things/little_things_example.dart',
    'The exception family, the request id, and the error envelope',
  ),
];

/// The example programs the tour does not run, and why.
///
/// Stating the reason is the point: a program left off a list with no reason
/// is indistinguishable from one forgotten.
const Map<String, String> notOnTheTour = {
  'example/scheduling/cluster/cluster_node.dart':
      'a cluster member: waits for peers and a shared MariaDB — run the three '
      'together with example/scheduling/cluster/run_cluster_demo.sh',
  'example/scheduling/cluster/cluster_provision.dart':
      'provisions the cluster schema in a live MariaDB',
  'example/scheduling/cluster/cluster_verify.dart':
      'reads the run table a live cluster produced',
  'example/example_reflection.dart':
      'the reflection generator root: its `main` is empty by contract',
};

Future<void> run() async {
  // Before spawning anything: a path that no longer resolves is a stop the
  // tour cannot take, and reporting it as "the example failed" would send a
  // reader looking for a defect in a file that has moved.
  for (final stop in tour) {
    check(
      File(stop.path).existsSync(),
      'the tour names ${stop.path}, which is not in this package',
    );
  }

  print('Tom Core Server — ${tour.length} example programs\n');

  final failed = <String>[];
  for (var i = 0; i < tour.length; i++) {
    final stop = tour[i];
    print('═' * 72);
    print('[${i + 1}/${tour.length}] ${stop.path}');
    print('         ${stop.shows}');
    print('═' * 72);

    final result = await Process.run(Platform.resolvedExecutable, [
      'run',
      stop.path,
    ]);
    stdout.write(result.stdout);
    stderr.write(result.stderr);
    if (result.exitCode != 0) failed.add(stop.path);
    print('');
  }

  print('═' * 72);
  // Every program is run before anything is reported: a reader who wants the
  // whole set wants to know which of them failed, not only the first.
  print(
    failed.isEmpty
        ? '${tour.length} examples, all green.'
        : '${failed.length} of ${tour.length} examples failed:\n'
              '  ${failed.join('\n  ')}',
  );
  check(failed.isEmpty, 'every example on the tour has to exit 0');
}

Future<void> main() => run();