Agent skill
adobe-reference-architecture
Implement Adobe reference architecture for production integrations covering Firefly Services, PDF Services, I/O Events, and App Builder with layered project layout, error boundaries, and health monitoring. Trigger with phrases like "adobe architecture", "adobe project structure", "how to organize adobe", "adobe layout", "adobe best practices".
Install this agent skill to your Project
npx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/main/plugins/saas-packs/adobe-pack/skills/adobe-reference-architecture
SKILL.md
Adobe Reference Architecture
Overview
Production-ready architecture patterns for Adobe API integrations, designed around the three main API families: Firefly Services (creative AI), PDF Services (document automation), and I/O Events (event-driven).
Prerequisites
- Understanding of layered architecture
- TypeScript project setup
- Decision on which Adobe APIs to integrate
Instructions
Step 1: Project Structure
my-adobe-project/
├── src/
│ ├── adobe/ # Adobe client layer
│ │ ├── auth.ts # OAuth Server-to-Server token management
│ │ ├── firefly-client.ts # Firefly API wrapper (generate, fill, expand)
│ │ ├── pdf-client.ts # PDF Services wrapper (create, extract, merge)
│ │ ├── photoshop-client.ts # Photoshop API wrapper (cutout, actions)
│ │ ├── events-client.ts # I/O Events registration and verification
│ │ ├── types.ts # Shared Adobe types
│ │ └── errors.ts # Error classification (retryable vs permanent)
│ ├── services/ # Business logic layer
│ │ ├── image-generation.ts # Orchestrates Firefly + Photoshop workflows
│ │ ├── document-pipeline.ts # Orchestrates PDF create/extract/merge
│ │ └── event-processor.ts # Routes and processes I/O Events
│ ├── api/ # API layer (routes, controllers)
│ │ ├── health.ts # Health check including Adobe IMS
│ │ ├── webhooks/adobe.ts # I/O Events webhook endpoint
│ │ └── routes/
│ │ ├── images.ts # Image generation endpoints
│ │ └── documents.ts # Document processing endpoints
│ ├── jobs/ # Background job layer
│ │ ├── firefly-batch.ts # Batch image generation queue
│ │ └── pdf-extraction.ts # Async PDF extraction worker
│ └── index.ts
├── tests/
│ ├── unit/
│ │ ├── adobe/auth.test.ts
│ │ └── services/
│ └── integration/
│ └── adobe/
│ ├── firefly.test.ts
│ └── pdf-services.test.ts
├── config/
│ ├── adobe.development.json
│ ├── adobe.staging.json
│ └── adobe.production.json
└── package.json
Step 2: Layer Architecture
┌─────────────────────────────────────────────────────┐
│ API Layer │
│ Routes, Controllers, Webhook Endpoints │
├─────────────────────────────────────────────────────┤
│ Service Layer │
│ Business Logic, Workflow Orchestration │
│ (image-generation.ts, document-pipeline.ts) │
├─────────────────────────────────────────────────────┤
│ Adobe Client Layer │
│ auth.ts, firefly-client.ts, pdf-client.ts │
│ Token caching, retry, error classification │
├─────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│ Cache (LRU/Redis), Queue (BullMQ), Monitoring │
└─────────────────────────────────────────────────────┘
Rules:
- API layer never calls Adobe APIs directly — always through Service layer
- Service layer orchestrates multiple Adobe clients (e.g., Firefly + Photoshop)
- Adobe Client layer handles auth, retry, error classification
- Infrastructure layer is swappable (in-memory cache for dev, Redis for prod)
Step 3: Error Boundary
// src/adobe/errors.ts
export class AdobeServiceError extends Error {
constructor(
message: string,
public readonly code: string,
public readonly httpStatus: number,
public readonly retryable: boolean,
public readonly api: 'firefly' | 'pdf-services' | 'photoshop' | 'events',
public readonly retryAfter?: number,
public readonly originalError?: Error
) {
super(message);
this.name = 'AdobeServiceError';
}
static fromResponse(api: string, status: number, body: string, headers?: Headers): AdobeServiceError {
const retryAfter = headers?.get('Retry-After');
return new AdobeServiceError(
`Adobe ${api} API error (${status}): ${body.slice(0, 200)}`,
status === 429 ? 'RATE_LIMITED' :
status === 401 ? 'AUTH_EXPIRED' :
status >= 500 ? 'SERVER_ERROR' : 'CLIENT_ERROR',
status,
status === 429 || status >= 500,
api as any,
retryAfter ? parseInt(retryAfter) : undefined,
);
}
}
Step 4: Configuration Management
// config/adobe.ts
export interface AdobeConfig {
clientId: string;
clientSecret: string;
scopes: string;
environment: 'development' | 'staging' | 'production';
apis: {
firefly: { enabled: boolean; baseUrl: string };
pdfServices: { enabled: boolean };
photoshop: { enabled: boolean; baseUrl: string };
events: { enabled: boolean; webhookUrl: string };
};
retry: { maxRetries: number; baseDelayMs: number };
cache: { enabled: boolean; ttlSeconds: number };
}
export function loadConfig(): AdobeConfig {
const env = process.env.NODE_ENV || 'development';
const base = require(`./adobe.${env}.json`);
return {
...base,
clientId: process.env.ADOBE_CLIENT_ID!,
clientSecret: process.env.ADOBE_CLIENT_SECRET!,
scopes: process.env.ADOBE_SCOPES!,
environment: env as any,
};
}
Step 5: Health Check
// src/api/health.ts
export async function adobeHealthCheck(config: AdobeConfig) {
const checks: Record<string, any> = {};
// Always check IMS auth
try {
const start = Date.now();
await getCachedToken();
checks.ims = { status: 'healthy', latencyMs: Date.now() - start };
} catch (e: any) {
checks.ims = { status: 'unhealthy', error: e.message };
}
// Check enabled APIs
if (config.apis.firefly.enabled) {
checks.firefly = await pingEndpoint('https://firefly-api.adobe.io');
}
if (config.apis.photoshop.enabled) {
checks.photoshop = await pingEndpoint('https://image.adobe.io');
}
const overall = Object.values(checks).every(
(c: any) => c.status === 'healthy'
) ? 'healthy' : 'degraded';
return { status: overall, services: checks };
}
Data Flow
User Request
│
▼
┌─────────────┐
│ Express │ ← Webhook from Adobe I/O Events
│ Router │
└──────┬───┬──┘
│ │
▼ ▼
┌────────┐ ┌────────────┐
│Service │ │Event │
│Layer │ │Processor │
└───┬────┘ └──────┬─────┘
│ │
▼ ▼
┌──────────────────────┐ ┌─────────┐
│ Adobe Client Layer │───▶│ Cache │
│ (auth + API calls) │ │ LRU/Redis│
└──────────┬───────────┘ └─────────┘
│
┌──────┼──────┐
▼ ▼ ▼
┌──────┐┌──────┐┌──────┐
│Firefly││PDF ││Photo │
│API ││Svc ││shop │
└──────┘└──────┘└──────┘
Output
- Layered project structure separating concerns
- Error boundary with classification and retry logic
- Per-environment configuration with secret injection
- Health check covering IMS and all enabled APIs
Resources
Next Steps
For multi-environment setup, see adobe-multi-env-setup.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
dockerfile-generator
Dockerfile Generator - Auto-activating skill for DevOps Basics. Triggers on: dockerfile generator, dockerfile generator Part of the DevOps Basics skill category.
branch-naming-helper
Branch Naming Helper - Auto-activating skill for DevOps Basics. Triggers on: branch naming helper, branch naming helper Part of the DevOps Basics skill category.
readme-generator
Readme Generator - Auto-activating skill for DevOps Basics. Triggers on: readme generator, readme generator Part of the DevOps Basics skill category.
makefile-generator
Makefile Generator - Auto-activating skill for DevOps Basics. Triggers on: makefile generator, makefile generator Part of the DevOps Basics skill category.
gitignore-generator
Gitignore Generator - Auto-activating skill for DevOps Basics. Triggers on: gitignore generator, gitignore generator Part of the DevOps Basics skill category.
pre-commit-hook-setup
Pre Commit Hook Setup - Auto-activating skill for DevOps Basics. Triggers on: pre commit hook setup, pre commit hook setup Part of the DevOps Basics skill category.
Didn't find tool you were looking for?