/** * App documents — `apps//dql.app.json`. * * An App is the consumption surface for stakeholders/CXO/teams. It bundles * dashboards, notebooks, members, roles, access policies, RLS bindings, * schedules, and a homepage into a single git-versioned artifact. * * Identity stays single-user in OSS; roles and policies are programmable and * enforced via the existing dql-governance PolicyEngine + the @rls compiler * decorator. Real SSO is layered separately in closed product. */ import { type ProductDomainContext } from './product-domain-context.js'; export type AppRole = { id: string; displayName?: string; description?: string; }; export type AppMember = { /** Stable user identifier. In OSS this is a free-form string (e.g. email). */ userId: string; /** Optional display name shown in the persona switcher. */ displayName?: string; /** Roles assigned to this member within the App. */ roles: string[]; /** Free-form attributes used to resolve RLS template variables (e.g. `region`). */ attributes?: Record; }; export type AppPolicy = { id: string; description?: string; /** Domain this policy applies to, or '*' for all. */ domain: string; /** Minimum data classification this policy permits. */ minClassification: 'public' | 'internal' | 'confidential' | 'restricted'; /** Roles granted access. */ allowedRoles: string[]; /** Specific user IDs granted access (overrides roles). */ allowedUsers?: string[]; /** Access level granted by this policy. */ accessLevel: 'read' | 'write' | 'execute' | 'admin'; enabled?: boolean; }; export type AppRlsBinding = { /** Role this binding applies to. */ role: string; /** RLS template variable name (matches `{user.}` in @rls templates). */ variable: string; /** Member attribute key whose value populates the variable for that role. */ from: string; }; export type AppScheduleDelivery = { kind: 'slack'; channel: string; } | { kind: 'email'; to: string[]; } | { kind: 'webhook'; url: string; }; export type AppSchedule = { id: string; cron: string; /** Dashboard id (within this App) to render and deliver. */ dashboard: string; deliver: AppScheduleDelivery[]; /** Optional human-readable description. */ description?: string; enabled?: boolean; }; export type AppHomepage = { type: 'dashboard'; id: string; } | { type: 'notebook'; path: string; }; export type AppVisibility = 'shared' | 'private' | 'template'; export type AppLifecycle = 'draft' | 'review' | 'certified' | 'deprecated'; export type AppPublicationIntent = 'personal' | 'shared_project'; export type AppNotebookRef = { path: string; title?: string; role: 'source' | 'analysis' | 'supporting'; visibility: AppVisibility; }; export interface AppDocument extends ProductDomainContext { /** Schema version for forward compatibility. */ version: 1; id: string; name: string; description?: string; businessOutcome?: string; businessOwner?: string; decisionUse?: string; reviewCadence?: string; businessRules?: string[]; caveats?: string[]; /** OSS organization metadata. Not an access-control boundary. */ visibility?: AppVisibility; /** Desired destination. Generated Apps remain private drafts until publish. */ publicationIntent?: AppPublicationIntent; /** v2 compatibility alias for ownerDomain. */ domain: string; subdomain?: string; groups?: string[]; audience?: string; lifecycle?: AppLifecycle; owners: string[]; tags?: string[]; notebooks?: AppNotebookRef[]; members: AppMember[]; roles: AppRole[]; policies: AppPolicy[]; rlsBindings?: AppRlsBinding[]; schedules?: AppSchedule[]; /** What stakeholders see when they open the App. */ homepage?: AppHomepage; /** Copilot hints (optional, additive): suggested questions the app's AI surfaces * offer — e.g. uncovered analysis gaps captured at AI-build time. */ copilot?: { suggestedQuestions: string[]; }; } export interface AppDocumentParseError { path: string; message: string; } export interface AppDocumentLoadResult { document: AppDocument | null; errors: AppDocumentParseError[]; } /** Parse a `dql.app.json` from raw text. */ export declare function parseAppDocument(text: string, path?: string): AppDocumentLoadResult; /** * Load and validate an App document by file path. * Returns errors instead of throwing so callers can surface them as diagnostics. */ export declare function loadAppDocument(filePath: string): AppDocumentLoadResult; /** * Discover all `dql.app.json` files under root `apps//` and domain-first * `domains//apps//` folders. * Returns absolute paths, sorted for deterministic manifest output. */ export declare function findAppDocuments(projectRoot: string): string[]; /** Normalize a member's attributes for RLS resolution. Always returns a plain object. */ export declare function memberAttributes(member: AppMember): Record; /** * Resolve `{user.}` RLS templates for a given member by walking * `rlsBindings` matching any of the member's roles. * * The first matching binding wins for each variable — bindings are * declared in role-priority order in `dql.app.json`. */ export declare function resolveRlsContext(app: AppDocument, member: AppMember): Record; /** Relative path of the App folder from the project root. */ export declare function appFolderRelPath(projectRoot: string, appJsonPath: string): string; /** Synthesize a folder-safe id when scaffolding a new App. Public for CLI use. */ export declare function suggestAppId(name: string): string; //# sourceMappingURL=app-document.d.ts.map