import { WorkflowDedupClient } from '@openhi/workflows';
import { EventBridgeEvent } from 'aws-lambda';
import { k as DemoDevUser, A as OnSiteTester } from './events-DsePbfmW.js';
import { O as OpenHiContext } from './openhi-context-CaBH8SFo.js';
import '@openhi/types';

/**
 * @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/seed-demo-data/seed-demo-data-handler.md
 *
 * EventBridge workflow handler invoked once per platform-deploy event
 * on the control event bus. Pre-flight verifies that
 * `seed-system-data` has already seeded the canonical Role records,
 * then idempotently re-asserts the demo-data graph: the placeholder
 * Tenant + Workspace, the three demo tenants + their workspaces, and
 * for each entry in {@link DEV_USERS} a Cognito user, a DynamoDB User,
 * 4 Memberships, 4 `tenant-admin` RoleAssignments, plus 1
 * platform-scoped `system-admin` RoleAssignment.
 */
type SeedDemoDataEvent = EventBridgeEvent<"platform.system-data-seeded.v1", unknown>;
/** Env var the lambda construct injects with the Cognito User Pool ID. */
declare const SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR = "SEED_DEMO_DATA_USER_POOL_ID";
/** Inputs the handler needs to provision Cognito users for every dev. */
interface CognitoProvisioner {
    /**
     * Ensure a Cognito user exists for `email`. Returns the user's
     * `sub`. Implementations MUST be idempotent: a second invocation
     * for the same email returns the existing user's sub without
     * resetting its password or touching any attribute.
     */
    readonly ensureUser: (email: string) => Promise<string>;
}
/**
 * Dependency seam for tests. The factory mirrors the production
 * arrangement: a real DynamoDB client + the real `workflowDedupClient`
 * factory bound to the `OPENHI_WORKFLOW_DEDUP_TABLE_NAME` env var the
 * construct injects via `grantConsumer`.
 */
interface SeedDemoDataDependencies {
    readonly dedupClient: WorkflowDedupClient;
    /**
     * Reads every id in `PLATFORM_ROLE_IDS`. Throws when any Role
     * record is missing — that means `seed-system-data` has not yet
     * run on this environment, and emitting demo RoleAssignments that
     * reference non-existent Roles would produce orphaned records.
     */
    readonly verifyRoles: () => Promise<void>;
    /**
     * Upserts every Tenant + Workspace in {@link DEMO_TENANT_SPECS},
     * plus per-dev-user Cognito users, DynamoDB User records,
     * Memberships, and RoleAssignments.
     */
    readonly seedDemoGraph: (params: {
        readonly baseContext: OpenHiContext;
        readonly devUsers: ReadonlyArray<DemoDevUser>;
        readonly cognito: CognitoProvisioner;
        readonly onSiteTesters?: ReadonlyArray<OnSiteTester>;
    }) => Promise<void>;
    /** Cognito provisioner threaded into `seedDemoGraph`. */
    readonly cognito: CognitoProvisioner;
}
/**
 * Upsert the full demo-data graph. Walks each spec in
 * {@link DEMO_TENANT_SPECS}: Tenant → Workspaces. Then per dev user:
 * Cognito user → DynamoDB User → per-tenant Membership +
 * `tenant-admin` RoleAssignment → platform-scoped `system-admin`
 * RoleAssignment. Finally walks {@link DEMO_DATA_PLANE_FIXTURES} and
 * upserts the OPS-009 v1 FHIR resource set (Patient, Practitioner,
 * Observation, Encounter, Account) into each demo workspace. Every
 * put is keyed by a deterministic stable id so re-runs after
 * dedup-TTL expiry upsert the same records.
 *
 * Self-healing-on-every-deploy contract: every individual upsert
 * across all three phases is wrapped via {@link tryRun}. A single
 * item's failure (transient AWS error, write-time constraint
 * violation, etc.) is collected into a per-call accumulator and
 * does not skip the remaining items in its phase. After all phases
 * run, collected failures are aggregate-thrown as a single error so
 * EventBridge still routes the workflow into its failure-detection
 * path (DLQ + CloudWatch alarm) and the outer `runSeedDemoData`
 * records `markFailed` on the dedup row. Because every put is keyed
 * by a deterministic stable id, the next deploy re-attempts every
 * item — failed items eventually heal, successful items overwrite
 * themselves with the same body.
 *
 * Exported so the seeder test file can exercise it directly against
 * a mocked DynamoControlService; the production handler reaches it
 * through {@link SeedDemoDataDependencies.seedDemoGraph}.
 */
declare const seedDemoGraph: (params: {
    baseContext: OpenHiContext;
    devUsers: ReadonlyArray<DemoDevUser>;
    cognito: CognitoProvisioner;
    onSiteTesters?: ReadonlyArray<OnSiteTester>;
    /**
     * ADR-028 counter-reconciliation seam (#1345). The seed writes
     * canonical Tenant / Workspace / Membership / RoleAssignment rows via
     * the create operations, which only *publish* counter-change events.
     * In the seed Lambda the control event bus is unset (so the publisher
     * is a no-op) and no consumer applies the deltas synchronously, so the
     * denormalized counters (`usersInTenant`, `workspacesInTenant`,
     * `tenantsForUser`, `workspacesForUser`, `usersInWorkspace`, …) would
     * stay `0`. After the control-plane phases land, this recomputes every
     * counter from canonical data with an absolute `SET`, so seeded counts
     * are correct without relying on the async event path. Idempotent on
     * re-seed (recompute-from-canonical, never increment), so a re-fire
     * never double-counts.
     *
     * Injected for tests; defaults to the real
     * {@link reconcileAllCountersOperation} the on-demand reconciliation
     * job uses.
     */
    reconcileCounters?: () => Promise<unknown>;
}) => Promise<void>;
/**
 * Test-visible orchestrator. The production `handler` calls this with
 * real dependencies and the hardcoded {@link DEV_USERS} list; unit
 * tests inject fakes and pass the dev-user list directly.
 */
declare const runSeedDemoData: (event: SeedDemoDataEvent, deps: SeedDemoDataDependencies, devUsers: ReadonlyArray<DemoDevUser>, onSiteTesters?: ReadonlyArray<OnSiteTester>) => Promise<void>;
/**
 * SSM parameter-path prefix that hosts every seeded dev user's
 * password. The full path for a single user is
 * `${SEED_USER_PASSWORD_PARAMETER_PREFIX}<email_safe>/password`
 * where `<email_safe>` is `<user>_at_<domain>` (see
 * {@link emailToSsmPath}). The trailing `/password` segment leaves
 * room for additional per-user parameters under the same email
 * prefix in future phases without renaming the existing entries.
 */
declare const SEED_USER_PASSWORD_PARAMETER_PREFIX = "/openhi/seed/users/";
/**
 * Map an email address to its canonical SSM parameter path. The
 * `@` separator is replaced with the literal sentinel `_at_` so
 * the resulting path is a single SSM-legal name. Throws when the
 * email is empty, missing exactly one `@`, or contains characters
 * that would produce an invalid SSM path.
 *
 * Example: `alice@codedrifters.com` →
 * `/openhi/seed/users/alice_at_codedrifters.com/password`.
 */
declare const emailToSsmPath: (email: string) => string;
/**
 * Test seam: reset the module-scoped SSM client cache. Unit tests
 * that swap in different mocks across `it` blocks call this in
 * `beforeEach` so each test gets a fresh client instance.
 */
declare const __resetSsmClientForTests: () => void;
/**
 * Read a seeded dev user's password from SSM Parameter Store. The
 * parameter is expected to be a `SecureString` provisioned out of
 * band by an operator (see the runbook in phase 3 of #1249). On
 * `ParameterNotFound`, the error message includes the exact
 * expected path so the operator can copy-paste-fix.
 */
declare const fetchSeedUserPassword: (email: string) => Promise<string>;
/**
 * Production Cognito provisioner backed by the AWS SDK. Reads the
 * user-pool id from the env var the lambda construct injects.
 *
 * Idempotency contract:
 *   - On first invocation, calls `AdminCreateUser` (with
 *     `MessageAction: SUPPRESS` so no invitation email fires) then
 *     `AdminSetUserPassword` (permanent, from the SSM-sourced
 *     value). Returns the new user's sub.
 *   - On subsequent invocations, `AdminCreateUser` throws
 *     `UsernameExistsException`; the provisioner catches it, calls
 *     `AdminGetUser` to read the existing user's sub, and **also
 *     re-applies the current SSM-sourced password** via
 *     `AdminSetUserPassword`. This is the rotation seam: operators
 *     update the SSM SecureString value and re-publish the seed
 *     event to push a fresh password down to Cognito.
 *
 * The SSM password is fetched once per email up-front so the new-
 * user and rotation branches share the same value and at most one
 * `GetParameter` call lands per `ensureUser` invocation.
 */
declare const productionCognitoProvisioner: () => CognitoProvisioner;
declare const handler: (event: SeedDemoDataEvent) => Promise<void>;

export { type CognitoProvisioner, SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR, SEED_USER_PASSWORD_PARAMETER_PREFIX, type SeedDemoDataDependencies, __resetSsmClientForTests, emailToSsmPath, fetchSeedUserPassword, handler, productionCognitoProvisioner, runSeedDemoData, seedDemoGraph };
