Skip to navigation

General Coding Conventions

  • Language: Use TypeScript with ES modules (import ... from ...), always including .js for local imports.
  • Error Handling:
    • Do not use process.env directly. Always use app.lookup(ENV_KEYS.KEY) for configuration and secrets.
    • In catch blocks, use unknown as the error type. Only access .message if error instanceof Error.
    • Use custom error classes from src/middleware/error.ts for HTTP errors.
  • Logging:
    • Use app.log for all logging. Never use console.log.
  • Dependency Injection:
    • Register services and controllers in the DI container in src/index.ts.
    • Use asClass for classes and asFunction for factories.
    • Controllers and services should receive dependencies via constructor injection.
  • Validation:
    • Use validation constants/types from src/constants/validation.ts and src/types/validation.ts.
    • Report validation errors using problem types from src/constants/problemTypes.ts.
  • Messaging & Pub/Sub:
    • Use SubscriptionHandler and SubscriptionMessageHandlers patterns for Service Bus subscriptions.
    • Use app.lookup(ENV_KEYS.KEY) for all topic and subscription names.
    • Use the utility in src/utils/serviceBusMessageUtils.ts for sending messages.
  • File/Blob Utilities:
    • Use src/utils/blobUtils.ts and src/utils/fileUtils.ts for blob/file operations.
    • Use BlobStorageService for Azure Blob Storage operations.
  • Controllers:
    • Extend BaseController and use its authenticate and authorize methods.
    • Do not access the DI container directly in controllers; use constructor injection.
  • Formatting & Linting:
    • Follow the ESLint rules in eslint.config.ts.
    • Do not use console.log or process.env.
    • Use single quotes, 4-space indentation, and trailing commas for multiline objects/arrays.
  • Testing:
    • Use Vitest for tests. Place unit tests in test/unit/, service tests in test/service/, and contract tests in test/contract/.
  • Documentation:
    • Add JSDoc comments for all public functions and classes.

File/Folder Structure

  • Place all source code in src/.
  • Place configuration constants in src/constants/.
  • Place type definitions in src/types/.
  • Place utility functions in src/utils/.
  • Place controllers in src/controllers/.
  • Place services in src/services/.
  • Place middleware in src/middleware/.
  • Place subscriptions in src/subscriptions/.

Example Patterns

  • Getting a config value:
const connectionString = await app.lookup(
ENV_KEYS.AZURE_SERVICE_BUS_CONNECTION_STRING
);
  • Error handling in async functions:
try {
// ...code...
} catch (error: unknown) {
if (error instanceof Error) {
app.log.error(error.message);
} else {
app.log.error("Unknown error", error);
}
throw error;
}
  • Registering a service in DI:
frameworkApp.server.diContainer.register({
fileService: asClass(FileService).scoped(),
});

applyTo

applyTo: [ ”/*.ts”, ”/*.js” ]


For more details, see Copilot custom instructions documentation.