fix(infrastructure): prevent .esbuild directory cleanup during packaging#542
Merged
seanspeaks merged 35 commits intofeature/integration-router-v2-drop-modules-routerfrom Feb 22, 2026
Conversation
Add comprehensive plan for Admin Script Runner service aligned with next branch architecture (command pattern, repository factories, Prisma schemas, multi-database support). Includes initial package structure for @friggframework/admin-scripts.
- Add AdminScriptBase.Definition following IntegrationBase pattern (ref: packages/core/integrations/integration-base.js:57-69) - Add appDefinition.adminScripts schema update (ref: packages/devtools/infrastructure/domains/shared/types/app-definition.js) - Make integrationFactory OPTIONAL for scripts that only need DB access - Add AdminFriggCommands with repository pattern matching existing commands - Include exact file references throughout plan
- ADR-5: Execution modes - sync (optional) vs async (default) - ADR-6: Hybrid scheduling (Definition defaults + DB/API overrides) - ADR-7: DDD/hexagonal architecture layers documented - ADR-8: SchedulerAdapter port with AWS/local implementations - ADR-9: AdminScriptBuilder following infrastructure-composer pattern - Add ScriptSchedule Prisma model for hybrid scheduling - Document deployment flow and generated serverless resources - Update package structure with adapters directory - Update Files to Create/Modify section with all new files
- ADR-10: Dry run via repository wrapper + HTTP interceptor - Intercepts DB writes, logs operations, returns unchanged data - Intercepts external API calls via mock axios instance - Script code unchanged between normal and dry-run modes - ADR-11: Self-queuing for long-running scripts - Scripts chunk work and re-queue via frigg.queueScript() - Tracks parentExecutionId for lineage - No Step Functions complexity - Remove VM sandbox (not needed for trusted adopter scripts) - Update package structure with dry-run files
- Replace raw SQS code with QueuerUtil.send() and batchSend() - Reference: packages/core/queues/queuer-util.js - Added queueScriptBatch() for bulk operations
Phase 1 implementation of Admin Script Runner service: Repository Layer: - AdminApiKey repositories (MongoDB, PostgreSQL, DocumentDB) - ScriptExecution repositories (MongoDB, PostgreSQL, DocumentDB) - Factory pattern for database-agnostic creation - 70 unit tests passing Application Layer: - createAdminScriptCommands() factory with: - API key management (create, validate, list, deactivate) - Execution lifecycle (create, update, complete) - bcrypt hashing for key security - Error mapping to HTTP status codes Infrastructure Layer: - AdminScriptBuilder wired into infrastructure-composer - Generates SQS queue, Lambda functions, EventBridge scheduler - 33 unit tests passing Prisma Schema: - AdminApiKey model with scopes and expiration - ScriptExecution model with status, logs, metrics
Application Layer: - AdminScriptBase: Base class for all admin scripts with Definition pattern - ScriptFactory: Registry for script registration and instantiation - AdminFriggCommands: Helper API for scripts (db access, queue, logging) - ScriptRunner: Orchestrates script execution with error handling Infrastructure Layer: - admin-auth-middleware: Bearer token authentication for admin API keys - admin-script-router: Express router with 5 endpoints for script management - script-executor-handler: SQS worker Lambda for async execution Features: - Sync and async execution modes - Self-queuing pattern via QueuerUtil for long-running scripts - Audit trail (API key, IP address) - Automatic log persistence to execution records Test Coverage: 110 tests passing
…h check Built-in Scripts: - OAuthTokenRefreshScript: Refreshes OAuth tokens near expiry - Configurable expiry threshold (default 24h) - Dry-run mode for safe testing - Filters by integration IDs or all - IntegrationHealthCheckScript: Checks integration health - Validates credential presence and expiry - Tests API connectivity - Optionally updates integration status - Schedule-ready (daily cron expression) Both scripts: - Extend AdminScriptBase with Definition pattern - Use AdminFriggCommands for database/API access - Include JSON Schema for input/output validation - Comprehensive error handling and logging Test Coverage: 41 tests passing for built-in scripts
Fixed a bug where the logs array from Prisma was being mutated directly instead of creating a copy first. This caused test failures when the original array reference was used for comparison.
Phase 2 - Hybrid Scheduling:
- ScriptSchedule Prisma model (MongoDB + PostgreSQL)
- ScriptSchedule repository implementations with factory
- SchedulerAdapter port interface (hexagonal pattern)
- AWSSchedulerAdapter for EventBridge Scheduler
- LocalSchedulerAdapter for dev/test
- Schedule management API endpoints:
- GET /scripts/:name/schedule (DB override > Definition default)
- PUT /scripts/:name/schedule (create/update override)
- DELETE /scripts/:name/schedule (revert to default)
- Schedule commands in admin-script-commands.js
Phase 3 - Dry-Run Mode:
- DryRunRepositoryWrapper: Proxy-based write interception
- DryRunHttpInterceptor: Mock HTTP client with service detection
- Automatic sanitization of sensitive data in logs
- Returns preview with operation log and summary
- POST /execute { dryRun: true } support
Features:
- 20+ external service detection (HubSpot, Salesforce, Slack, etc.)
- Smart read vs write operation detection
- Timezone-aware scheduling
- AWS EventBridge rule tracking (ruleArn, ruleName)
Test Coverage: 424 tests passing (141 new tests added)
- Remove commented-out domain model placeholders (not needed with repository pattern) - Remove commented-out factory function placeholder - Clarify EventBridge Scheduler integration comments as optional enhancement
- Integrate createSchedulerAdapter into PUT /schedule endpoint - Provision EventBridge rule when schedule is enabled with cron expression - Delete EventBridge rule when schedule is disabled or deleted - Store AWS rule ARN/name in database for tracking - Handle scheduler errors gracefully (non-fatal, with warning in response) - Add 6 new tests for scheduler integration
Align naming with AWS EventBridge Scheduler terminology: - awsRuleArn → awsScheduleArn - awsRuleName → awsScheduleName - updateScheduleAwsRule → updateScheduleAwsInfo - ruleArn → scheduleArn (adapter return values) - ruleName → scheduleName (adapter return values) This reflects that we use EventBridge Scheduler (the newer service), not EventBridge Rules (the older approach).
Document the design decisions for the Admin Script Runner: - Entry point via appDefinition.adminScripts - Script base class pattern following IntegrationBase - Infrastructure components (builder, repositories, handlers) - Execution modes (sync/async) - Hybrid scheduling with EventBridge Scheduler - Dry-run mode for safe testing - Security model with admin API keys Also update README to include ADR-004 and ADR-005.
The admin-script-router requires express and serverless-http but they were not declared in package.json, causing the release to fail.
The @unique constraint on keyHash already creates an index, so the explicit @@index([keyHash]) was causing a "Index already exists" error.
Replace global parseInt/isNaN with Number.parseInt/Number.isNaN to follow JavaScript best practices and pass SonarCloud analysis.
- Extract ScheduleManagementUseCase from admin-script-router - Encapsulates schedule business logic (get/upsert/delete) - Handles EventBridge sync with graceful error handling - 14 unit tests with full coverage - Refactor oauth-token-refresh.js - Extract _checkRefreshPrerequisites() for token validation - Extract _performTokenRefresh() for actual refresh logic - Extract _createResult() helper for consistent response format - Refactor integration-health-check.js - Extract _createCheckResult() for initial result structure - Extract _runChecks() to orchestrate all checks - Extract _addCheckResult() to track issues - Extract _determineOverallStatus() for status logic - Extract _handleCheckError() for error handling All 297 tests passing.
- Add id-token: write permission for OIDC authentication - Add contents: write permission for release commits - Upgrade npm to latest for trusted publishing support (requires 11.5.1+) - Remove NPM_TOKEN/NODE_AUTH_TOKEN (OIDC replaces token auth) Requires configuring trusted publishers on npmjs.com for each package.
Keep both OIDC permissions and NPM_TOKEN for flexibility: - Packages with trusted publisher configured → use OIDC - New packages (e.g., admin-scripts) → fall back to token This allows gradual migration to OIDC while supporting new package publishes.
Phase 1 of admin refactoring based on Daniel's PR review: 1. Auth simplification (ENV-based like db-migrate): - Add shared validateAdminApiKey middleware in core/handlers/middleware - Delete AdminApiKey model, repositories, and tests - Remove API key commands from admin-script-commands.js 2. Schema changes: - Replace AdminApiKey + ScriptExecution with AdminProcess model - AdminProcess mirrors Process but without user/integration FK - Supports hierarchy (parentProcessId, childProcesses) - Used for: admin scripts, db migrations, system tasks 3. Files deleted: - admin-api-key-repository-*.js (all variants) - admin-api-key tests Next steps: Create AdminProcess repository, refactor routes to /admin/scripts/:name convention, unify db-migrate under /admin.
…r /admin Major refactoring based on PR feedback: 1. AdminProcess Repository (replaces ScriptExecution): - New: admin-process-repository-interface.js - New: admin-process-repository-mongo.js - New: admin-process-repository-postgres.js - New: admin-process-repository-documentdb.js - New: admin-process-repository-factory.js - Deleted: All script-execution-repository-* files 2. Updated admin-scripts package: - All files now use AdminProcess methods - Updated: admin-script-base.js, admin-frigg-commands.js, script-runner.js - Updated: admin-script-router.js, script-executor-handler.js - Fixed export: validateAdminApiKey (not adminAuthMiddleware) 3. Moved db-migrate under /admin path: - Routes: /admin/db-migrate/* - Uses shared validateAdminApiKey middleware - Updated use-cases and tests 4. Cleaned up obsolete code: - Removed AdminApiKey tests from admin-script-commands.test.js - Updated all tests for AdminProcess methods All 295 tests passing.
Address PR feedback from Daniel: 1. Simplified dry-run implementation: - Deleted over-engineered dry-run-repository-wrapper.js (262 lines) - Deleted over-engineered dry-run-http-interceptor.js (297 lines) - New dry-run validates inputs and returns preview without executing - Added JSON schema validation for script parameters - Net reduction: ~990 lines removed 2. Cleaned up package.json: - Removed unused mongoose dependency - Removed unused chai devDependency - Kept supertest for Express route testing (different from nock) 3. Documented admin-script-commands architecture: - Explained why separate from integration-commands - integration-commands: user-context operations (requires integrationClass) - admin-script-commands: system operations (no user context) - Separation follows SRP and avoids coupling Tests: 262 passing
…Runner Changes: - Rename requiresIntegrationFactory to requireIntegrationInstance (PR feedback) - Add JSDoc documentation for executionId parameter - Split schedule-management-use-case.js into 3 separate use cases following SRP: - GetEffectiveScheduleUseCase - UpsertScheduleUseCase - DeleteScheduleUseCase - Abstract AWS-specific naming to generic external scheduler terminology: - awsScheduleArn → externalScheduleId - awsScheduleName → externalScheduleName - updateScheduleAwsInfo → updateScheduleExternalInfo - Remove sinon dependency, use Jest mocks instead - Update Prisma schemas for both MongoDB and PostgreSQL - Update ADR documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ename context - Rename AdminFriggCommands → AdminScriptContext (facade pattern) - Refactor to constructor injection (context via constructor, not execute) - Remove logging from AdminScriptBase (use context.log instead) - Clean up display object - only UI-specific overrides - Strip verbose JSDoc comments (keep code sparse) - Update all tests for new API - Add PR review tracker for remaining items 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…leanup - Remove hardcoded defaults and env var auto-detection from scheduler adapters; require explicit config from appDefinition pattern - Region inherits from AWS_REGION (Lambda runtime), not per-adapter config - Make trigger required in ScriptRunner.execute() - Fix status->state bug in script-executor-handler error path - Remove PR_517_REVIEW_TRACKER.md from repo - Regenerate package-lock.json (remove stale mongoose/chai/sinon) - Remove detectSchedulerAdapterType and its export Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… handler - Extract dry-run validation from ScriptRunner into standalone validateScriptInput() with dedicated POST /scripts/:name/validate route - Simplify script-executor-handler to thin SQS adapter; runner handles all error recording and status updates - Change async execution response status from PENDING to QUEUED - Remove dryRun param from execute endpoint (separate concerns) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d SQS validation - Remove 12 thin wrapper methods from AdminScriptContext; scripts now access repos directly via context.integrationRepository, etc. - Remove DB log persistence from log(); in-memory only now - Remove adminProcessRepository lazy getter (no longer needed) - Add JSDoc documenting AdminScriptContext's unique value - Remove 5 static helpers from AdminScriptBase (getName, getDefinition, etc.) - Update builtin scripts to use repos directly - Add scriptName/executionId validation in SQS handler - Update all tests (-529/+149 lines) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, queue validation, unused deps - Pass scheduler config from env vars to createSchedulerAdapter() instead of empty call - Validate ADMIN_SCRIPT_QUEUE_URL before async execution, return 503 if not configured - Remove unused bcryptjs, lodash, uuid dependencies Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…racking, adapter format - AWS scheduler createSchedule now uses upsert pattern: tries CreateScheduleCommand first, falls back to UpdateScheduleCommand on ConflictException, preventing stale schedules when cron expressions are edited - SQS handler catch block now calls completeAdminProcess with state: 'FAILED' when executionId is available, preventing orphaned execution records stuck in non-terminal state - LocalSchedulerAdapter.listSchedules() now returns normalized format matching AWS adapter contract (Name, State, ScheduleExpression, ScheduleExpressionTimezone) https://claude.ai/code/session_01BRAKMNfvY2Fpnwac7gbuq3
Resolves merge conflicts by taking the admin-script-runner branch's versions for admin-scripts models (AdminProcess pattern), /admin/ route prefixes, admin auth middleware, and vendor-agnostic scheduler naming. https://claude.ai/code/session_01UTMSBwVwDXaGTmtnNJ8VX6
… exports - Fix method name mismatch in admin-script-commands.js: commands now call repository interface methods (createProcess, findProcessById, etc.) instead of non-existent domain-specific names (createAdminProcess, etc.) - Translate command params to repository format (scriptName→name, type→ADMIN_SCRIPT, context object for scriptVersion/trigger/mode/input/audit) - Consolidate completeAdminProcess to use single updateProcessResults call instead of separate updateOutput/updateError/updateMetrics methods - Export createAdminScriptCommands from application/index.js and core/index.js - Standardize requireAdmin middleware to use x-frigg-admin-api-key header (consistent with validateAdminApiKey middleware) - Add missing mock for script-schedule-repository-factory in tests - Update all test assertions to match new repository interface contract https://claude.ai/code/session_01UTMSBwVwDXaGTmtnNJ8VX6
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 22520632 | Triggered | Generic High Entropy Secret | 29da1f3 | packages/core/credential/repositories/tests/credential-repository-documentdb-encryption.test.js | View secret |
| 23374074 | Triggered | Generic Password | 8c6a058 | packages/devtools/frigg-cli/start-command/infrastructure/DatabaseAdapter.js | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
0eec050
into
feature/integration-router-v2-drop-modules-router
9 of 24 checks passed
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Problem
Deployment fails with ENOENT error during serverless packaging:
Root Cause
serverless-esbuild config had
keepOutputDirectory: false, which causes:.esbuild/.serverlessdirectory.esbuilddirectory (cleanup).esbuild/.serverless→ ENOENTSolution
Set
keepOutputDirectory: truein base-definition-factory.js:227Why This Is Safe:
Testing
Local development unaffected (directory already exists during dev)
CI/CD will no longer fail with ENOENT during packaging
Impact
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com