UNPKG

adpa-enterprise-framework-automation

Version:

Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe

894 lines (756 loc) 17.9 kB
# TypeSpec Implementation Guide for ADPA ## Getting Started with TypeSpec This guide provides step-by-step instructions for implementing TypeSpec in the ADPA project to create a professional API-first document processing platform. ## Installation and Setup ### 1. Install TypeSpec ```bash # Install TypeSpec compiler and emitters npm install -g @typespec/compiler npm install --save-dev @typespec/http @typespec/rest @typespec/openapi3 ``` ### 2. Initialize TypeSpec Project ```bash # Create TypeSpec configuration in your project mkdir api-specs cd api-specs tsp init ``` ### 3. Project Structure ``` adpa-api-specs/ ├── tspconfig.yaml # TypeSpec configuration ├── main.tsp # Main API specification ├── models/ ├── common.tsp # Shared types and models ├── document.tsp # Document processing models ├── template.tsp # Template management models └── errors.tsp # Error handling models ├── services/ ├── document-api.tsp # Document processing endpoints ├── template-api.tsp # Template management endpoints └── health-api.tsp # Health check endpoints └── generated/ ├── openapi/ # Generated OpenAPI specs └── clients/ # Generated client SDKs ``` ## Core ADPA API Specification ### 1. Main TypeSpec File (`main.tsp`) ```typescript import "@typespec/http"; import "@typespec/rest"; import "@typespec/openapi3"; using TypeSpec.Http; using TypeSpec.Rest; @service({ title: "ADPA Document Processing API", version: "1.0.0", description: "Professional document processing and conversion API" }) @server("https://api.adpa.io", "Production server") @server("https://api-staging.adpa.io", "Staging server") namespace ADPA; // Import models and services import "./models/common.tsp"; import "./models/document.tsp"; import "./models/template.tsp"; import "./models/errors.tsp"; import "./services/document-api.tsp"; import "./services/template-api.tsp"; import "./services/health-api.tsp"; ``` ### 2. Common Models (`models/common.tsp`) ```typescript namespace ADPA.Models; /** * Standard API response wrapper */ model ApiResponse<T> { success: boolean; data?: T; error?: ErrorDetail; timestamp: utcDateTime; requestId: string; } /** * Pagination parameters */ model PaginationParams { @query page?: int32 = 1; @query limit?: int32 = 20; @query sort?: string; @query order?: "asc" | "desc" = "asc"; } /** * Pagination response */ model PaginatedResponse<T> { items: T[]; pagination: { page: int32; limit: int32; total: int32; totalPages: int32; hasNext: boolean; hasPrev: boolean; }; } /** * Metadata for documents */ model DocumentMetadata { title?: string; author?: string; subject?: string; keywords?: string[]; createdAt?: utcDateTime; modifiedAt?: utcDateTime; tags?: string[]; customProperties?: Record<string>; } /** * Processing status enumeration */ enum ProcessingStatus { queued: "queued", processing: "processing", completed: "completed", failed: "failed", cancelled: "cancelled" } ``` ### 3. Document Processing Models (`models/document.tsp`) ```typescript namespace ADPA.Models; /** * Supported input formats */ enum InputFormat { markdown: "markdown", html: "html", docx: "docx", txt: "txt" } /** * Supported output formats */ enum OutputFormat { pdf: "pdf", docx: "docx", html: "html", pptx: "pptx" } /** * Document conversion request */ model DocumentConversionRequest { /** * Source document content or URL */ @minLength(1) content: string; /** * Input format of the source document */ inputFormat: InputFormat; /** * Desired output format */ outputFormat: OutputFormat; /** * Template to use for conversion */ templateId?: string; /** * Document metadata */ metadata?: DocumentMetadata; /** * Conversion options */ options?: ConversionOptions; /** * Webhook URL for completion notification */ webhookUrl?: url; } /** * Conversion options */ model ConversionOptions { /** * Page size for PDF output */ pageSize?: "A4" | "A3" | "Letter" | "Legal"; /** * Page orientation */ orientation?: "portrait" | "landscape"; /** * Include table of contents */ includeTableOfContents?: boolean; /** * Include page numbers */ includePageNumbers?: boolean; /** * Custom CSS for styling */ customCss?: string; /** * DPI for image rendering */ dpi?: int32; /** * Compression level (0-9) */ compression?: int32; /** * Password protection */ password?: string; } /** * Document conversion response */ model DocumentConversionResponse { /** * Unique job identifier */ jobId: string; /** * Current processing status */ status: ProcessingStatus; /** * Download URL (available when completed) */ downloadUrl?: url; /** * File size in bytes */ fileSize?: int64; /** * Processing progress (0-100) */ progress?: int32; /** * Estimated completion time */ estimatedCompletion?: utcDateTime; /** * Created timestamp */ createdAt: utcDateTime; /** * Completed timestamp */ completedAt?: utcDateTime; /** * Error details if failed */ error?: ProcessingError; } /** * Processing error details */ model ProcessingError { code: string; message: string; details?: string; retryable: boolean; } /** * Batch conversion request */ model BatchConversionRequest { /** * List of documents to convert */ @minItems(1) @maxItems(100) documents: DocumentConversionRequest[]; /** * Batch processing options */ options?: BatchOptions; } /** * Batch processing options */ model BatchOptions { /** * Maximum parallel conversions */ maxParallel?: int32; /** * Continue on individual failures */ continueOnError?: boolean; /** * Batch completion webhook */ webhookUrl?: url; } /** * Batch conversion response */ model BatchConversionResponse { /** * Batch job identifier */ batchId: string; /** * Individual job responses */ jobs: DocumentConversionResponse[]; /** * Overall batch status */ status: ProcessingStatus; /** * Batch progress (0-100) */ progress: int32; /** * Created timestamp */ createdAt: utcDateTime; } ``` ### 4. Document Processing API (`services/document-api.tsp`) ```typescript namespace ADPA.Services; using ADPA.Models; @tag("Document Processing") @route("/api/v1/documents") interface DocumentAPI { /** * Convert a single document */ @post @route("/convert") convertDocument( @body request: DocumentConversionRequest ): ApiResponse<DocumentConversionResponse>; /** * Convert multiple documents in batch */ @post @route("/batch/convert") batchConvert( @body request: BatchConversionRequest ): ApiResponse<BatchConversionResponse>; /** * Get conversion job status */ @get @route("/jobs/{jobId}") getJobStatus( @path jobId: string ): ApiResponse<DocumentConversionResponse>; /** * Get batch conversion status */ @get @route("/batch/{batchId}") getBatchStatus( @path batchId: string ): ApiResponse<BatchConversionResponse>; /** * Download converted document */ @get @route("/download/{jobId}") downloadDocument( @path jobId: string ): { @header("Content-Type") contentType: string; @header("Content-Disposition") contentDisposition: string; @body content: bytes; }; /** * Cancel conversion job */ @delete @route("/jobs/{jobId}") cancelJob( @path jobId: string ): ApiResponse<void>; /** * List conversion jobs */ @get @route("/jobs") listJobs( ...PaginationParams, @query status?: ProcessingStatus, @query fromDate?: utcDateTime, @query toDate?: utcDateTime ): ApiResponse<PaginatedResponse<DocumentConversionResponse>>; /** * Get conversion statistics */ @get @route("/stats") getStats( @query fromDate?: utcDateTime, @query toDate?: utcDateTime ): ApiResponse<{ totalJobs: int32; successfulJobs: int32; failedJobs: int32; processingTime: { average: int32; min: int32; max: int32; }; formatBreakdown: Record<int32>; }>; } ``` ### 5. Template Management API (`services/template-api.tsp`) ```typescript namespace ADPA.Services; using ADPA.Models; /** * Template model */ model Template { id: string; name: string; description?: string; format: OutputFormat; content: string; variables?: string[]; createdAt: utcDateTime; updatedAt: utcDateTime; version: int32; isActive: boolean; metadata?: Record<string>; } /** * Template creation request */ model CreateTemplateRequest { @minLength(1) name: string; description?: string; format: OutputFormat; @minLength(1) content: string; variables?: string[]; metadata?: Record<string>; } /** * Template update request */ model UpdateTemplateRequest { name?: string; description?: string; content?: string; variables?: string[]; isActive?: boolean; metadata?: Record<string>; } @tag("Template Management") @route("/api/v1/templates") interface TemplateAPI { /** * Create a new template */ @post createTemplate( @body request: CreateTemplateRequest ): ApiResponse<Template>; /** * Get template by ID */ @get @route("/{templateId}") getTemplate( @path templateId: string ): ApiResponse<Template>; /** * Update template */ @put @route("/{templateId}") updateTemplate( @path templateId: string, @body request: UpdateTemplateRequest ): ApiResponse<Template>; /** * Delete template */ @delete @route("/{templateId}") deleteTemplate( @path templateId: string ): ApiResponse<void>; /** * List templates */ @get listTemplates( ...PaginationParams, @query format?: OutputFormat, @query active?: boolean ): ApiResponse<PaginatedResponse<Template>>; /** * Preview template with sample data */ @post @route("/{templateId}/preview") previewTemplate( @path templateId: string, @body data: Record<unknown> ): ApiResponse<{ previewUrl: url; expiresAt: utcDateTime; }>; } ``` ### 6. Error Models (`models/errors.tsp`) ```typescript namespace ADPA.Models; /** * Standard error response */ model ErrorDetail { /** * Error code */ code: string; /** * Human-readable error message */ message: string; /** * Additional error details */ details?: string; /** * Field-specific errors for validation */ fieldErrors?: Record<string[]>; /** * Unique error identifier for tracking */ errorId?: string; /** * Timestamp when error occurred */ timestamp: utcDateTime; } /** * Error response with proper HTTP status codes */ @error model BadRequestError { @statusCode statusCode: 400; @body error: ErrorDetail; } @error model UnauthorizedError { @statusCode statusCode: 401; @body error: ErrorDetail; } @error model ForbiddenError { @statusCode statusCode: 403; @body error: ErrorDetail; } @error model NotFoundError { @statusCode statusCode: 404; @body error: ErrorDetail; } @error model UnprocessableEntityError { @statusCode statusCode: 422; @body error: ErrorDetail; } @error model TooManyRequestsError { @statusCode statusCode: 429; @body error: ErrorDetail; } @error model InternalServerError { @statusCode statusCode: 500; @body error: ErrorDetail; } @error model ServiceUnavailableError { @statusCode statusCode: 503; @body error: ErrorDetail; } ``` ### 7. Health Check API (`services/health-api.tsp`) ```typescript namespace ADPA.Services; /** * Health check response */ model HealthCheckResponse { status: "healthy" | "degraded" | "unhealthy"; version: string; uptime: int64; checks: { database: HealthStatus; queue: HealthStatus; storage: HealthStatus; adobe: HealthStatus; }; timestamp: utcDateTime; } /** * Individual health status */ model HealthStatus { status: "healthy" | "degraded" | "unhealthy"; responseTime?: int32; message?: string; } @tag("Health") @route("/api/v1/health") interface HealthAPI { /** * Get service health status */ @get getHealth(): HealthCheckResponse; /** * Get readiness status */ @get @route("/ready") getReadiness(): { ready: boolean; timestamp: utcDateTime; }; /** * Get liveness status */ @get @route("/live") getLiveness(): { alive: boolean; timestamp: utcDateTime; }; } ``` ## Configuration and Generation ### 1. TypeSpec Configuration (`tspconfig.yaml`) ```yaml emit: - "@typespec/openapi3" - "@typespec/json-schema" options: "@typespec/openapi3": output-file: "generated/openapi/adpa-api.yaml" version: "3.0.3" title: "ADPA Document Processing API" description: "Professional document processing and conversion API" "@typespec/json-schema": output-dir: "generated/schemas" linter: extends: - "@typespec/best-practices" rules: no-closed-literal-union: "warn" require-docs: "error" ``` ### 2. Build Scripts Add to your `package.json`: ```json { "scripts": { "api:compile": "tsp compile api-specs", "api:watch": "tsp compile api-specs --watch", "api:format": "tsp format api-specs/**/*.tsp", "api:lint": "tsp compile api-specs --no-emit", "api:generate-clients": "npm run api:generate-js && npm run api:generate-python", "api:generate-js": "openapi-generator-cli generate -i generated/openapi/adpa-api.yaml -g typescript-axios -o generated/clients/typescript", "api:generate-python": "openapi-generator-cli generate -i generated/openapi/adpa-api.yaml -g python -o generated/clients/python", "api:docs": "redoc-cli build generated/openapi/adpa-api.yaml --output docs/api/index.html" } } ``` ### 3. Generate API Artifacts ```bash # Compile TypeSpec and generate OpenAPI npm run api:compile # Generate client SDKs npm run api:generate-clients # Generate API documentation npm run api:docs # Watch for changes npm run api:watch ``` ## Integration with Existing ADPA ### 1. Express.js Server Implementation ```typescript // src/api/server.ts import express from 'express'; import { DocumentController } from './controllers/DocumentController'; import { TemplateController } from './controllers/TemplateController'; import { HealthController } from './controllers/HealthController'; const app = express(); app.use(express.json()); // Document processing routes app.post('/api/v1/documents/convert', DocumentController.convertDocument); app.post('/api/v1/documents/batch/convert', DocumentController.batchConvert); app.get('/api/v1/documents/jobs/:jobId', DocumentController.getJobStatus); app.get('/api/v1/documents/download/:jobId', DocumentController.downloadDocument); // Template management routes app.post('/api/v1/templates', TemplateController.createTemplate); app.get('/api/v1/templates/:templateId', TemplateController.getTemplate); app.put('/api/v1/templates/:templateId', TemplateController.updateTemplate); // Health check routes app.get('/api/v1/health', HealthController.getHealth); app.get('/api/v1/health/ready', HealthController.getReadiness); export { app }; ``` ### 2. Document Controller Implementation ```typescript // src/api/controllers/DocumentController.ts import { Request, Response } from 'express'; import { DocumentConversionRequest, DocumentConversionResponse } from '../generated/types'; import { DocumentProcessor } from '../services/DocumentProcessor'; export class DocumentController { static async convertDocument(req: Request, res: Response) { try { const request: DocumentConversionRequest = req.body; const processor = new DocumentProcessor(); const response = await processor.convertDocument(request); res.json({ success: true, data: response, timestamp: new Date().toISOString(), requestId: req.headers['x-request-id'] || 'unknown' }); } catch (error) { res.status(500).json({ success: false, error: { code: 'CONVERSION_FAILED', message: error.message, timestamp: new Date().toISOString() } }); } } // Additional controller methods... } ``` ## Next Steps 1. **Set up TypeSpec project structure** 2. **Define core API specifications** 3. **Generate OpenAPI documentation** 4. **Implement server controllers** 5. **Generate and test client SDKs** 6. **Deploy API documentation** 7. **Integrate with existing ADPA CLI** This TypeSpec implementation provides a solid foundation for transforming ADPA into a professional API-first document processing platform with enterprise-grade capabilities.