10 KiB
10 KiB
Operational Guidelines
This document is a granulated shard from the main "3-architecture.md" focusing on "Operational Guidelines (Coding Standards, Testing, Error Handling, Security)".
Error Handling Strategy
A robust error handling strategy is essential for the reliability of the BMad DiCaster pipeline. This involves consistent error logging, appropriate retry mechanisms, and clear error propagation. The workflow_runs table will be a central piece in tracking errors for entire workflow executions.
- General Approach:
- Standard JavaScript
Errorobjects (or custom extensions ofError) will be used for exceptions within TypeScript code. - Each Supabase Function in the pipeline will catch its own errors, log them using Pino, update the
workflow_runstable with an error status/message (viaWorkflowTrackerService), and prevent unhandled promise rejections. - Next.js API routes will catch errors, log them, and return appropriate HTTP error responses (e.g., 4xx, 500) with a JSON error payload.
- Standard JavaScript
- Logging (Pino):
- Library/Method: Pino (
pino) is the standard logging library for Supabase Functions and Next.js API routes. - Configuration: A shared Pino logger instance (e.g.,
supabase/functions/_shared/logger.ts) will be configured for JSON output, ISO timestamps, and environment-aware pretty-printing for development.// Example: supabase/functions/_shared/logger.ts import pino from "pino"; export const logger = pino({ level: process.env.LOG_LEVEL || "info", formatters: { level: (label) => ({ level: label }) }, timestamp: pino.stdTimeFunctions.isoTime, ...(process.env.NODE_ENV === "development" && { transport: { target: "pino-pretty", options: { colorize: true, translateTime: "SYS:standard", ignore: "pid,hostname", }, }, }), }); - Format: Structured JSON.
- Levels:
trace,debug,info,warn,error,fatal. - Context: Logs must include
timestamp,severity,workflowRunId(where applicable),serviceorfunctionName, a clearmessage, and relevantdetails(sanitized). Sensitive data must NEVER be logged. Pass error objects directly to Pino:logger.error({ err: errorInstance, workflowRunId }, "Operation failed");.
- Library/Method: Pino (
- Specific Handling Patterns:
- External API Calls (HN Algolia, Play.ht, LLM Provider):
- Facades: Calls made through dedicated facades in
supabase/functions/_shared/. - Timeouts: Implement reasonable connect and read timeouts.
- Retries: Facades implement limited retries (2-3) with exponential backoff for transient errors (network issues, 5xx errors).
- Error Propagation: Facades catch, log, and throw standardized custom errors (e.g.,
ExternalApiError) containing contextual information.
- Facades: Calls made through dedicated facades in
- Internal Errors / Business Logic Exceptions (Supabase Functions):
- Use
try...catch. Critical errors preventing task completion for aworkflow_run_idmust: 1. Log detailed error (Pino). 2. CallWorkflowTrackerService.failWorkflow(...). - Next.js API routes return generic JSON errors (e.g.,
{"error": "Internal server error"}) and appropriate HTTP status codes.
- Use
- Database Operations (Supabase): Critical errors treated as internal errors (log, update
workflow_runsto 'failed'). - Scraping/Summarization/Podcast/Delivery Failures: Individual item failures are logged and status updated (e.g.,
scraped_articles.scraping_status). The overall workflow may continue with available data, with partial success noted inworkflow_runs.details. Systemic failures lead toworkflow_runs.status = 'failed'. CheckWorkflowCompletionService: Must be resilient. Errors processing oneworkflow_run_idshould be logged but not prevent processing of other runs or subsequent scheduled invocations.
- External API Calls (HN Algolia, Play.ht, LLM Provider):
Coding Standards
These standards are mandatory for all code generation by AI agents and human developers.
- Primary Language & Runtime: TypeScript
5.7.2, Node.js22.10.2. - Style Guide & Linter: ESLint (configured with Next.js defaults, TypeScript support) and Prettier (
3.3.3). Configurations in root. Linting/formatting are mandatory. - Naming Conventions:
- Variables & Functions/Methods:
camelCase - Classes/Types/Interfaces:
PascalCase - Constants:
UPPER_SNAKE_CASE - Files (.ts, .tsx):
kebab-case(e.g.,newsletter-card.tsx) - Supabase function directories:
kebab-case(e.g.,hn-content-service)
- Variables & Functions/Methods:
- File Structure: Adhere to "Project Structure." Unit tests (
*.test.ts(x)/*.spec.ts(x)) co-located with source files. - Asynchronous Operations: Always use
async/awaitfor Promises; ensure proper handling. - Type Safety (TypeScript): Adhere to
tsconfig.json("strict": true). Avoidany; useunknownwith type narrowing. Shared types inshared/types/. - Comments & Documentation: Explain why, not what. Use TSDoc for exported members. READMEs for modules/services.
- Dependency Management: Use
npm. Vet new dependencies. Pin versions or use^for non-breaking updates. Resolvelatesttags to specific versions upon setup. - Environment Variables: Manage via environment variables (
.env.exampleprovided). Use Zod for runtime parsing/validation. - Modularity & Reusability: Break down complexity. Use shared utilities/facades.
Detailed Language & Framework Conventions
TypeScript/Node.js (Next.js & Supabase Functions) Specifics:
- Immutability: Prefer immutable data structures (e.g.,
Readonly<T>,as const). Follow Zustand patterns for immutable state updates in React. - Functional vs. OOP: Favor functional constructs for data transformation/utilities. Use classes for services/facades managing state or as per framework (e.g., React functional components with Hooks preferred).
- Error Handling Specifics:
throw new Error('...')or custom error classes. EnsurePromiserejections areErrorobjects. - Null/Undefined Handling: With
strictNullChecks, handle explicitly. Avoid!non-null assertion; prefer explicit checks,?.,??. - Module System: Use ES Modules (
import/export) exclusively. - Logging Specifics (Pino): Use shared Pino logger. Include context object (
logger.info({ context }, "message")), especiallyworkflowRunId. - Next.js Conventions: Follow App Router conventions. Use Server Components for data fetching where appropriate. Route Handlers for API endpoints.
- Supabase Function Conventions:
index.tsas entry. Self-contained or use_shared/utilities. Secure client initialization (admin vs. user). - Code Generation Anti-Patterns to Avoid: Overly nested logic, single-letter variables (except trivial loops), disabling linter/TS errors without cause, bypassing framework security, monolithic functions.
Overall Testing Strategy
- Tools: Jest (unit/integration), React Testing Library (RTL) (React components), Playwright (E2E). Supabase CLI for local DB/function testing.
- Unit Tests:
- Scope: Isolate individual functions, methods, classes, React components. Focus on logic, transformations, component rendering.
- Location & Naming: Co-located with source files (
*.test.ts,*.spec.ts,*.test.tsx,*.spec.tsx). - Mocking/Stubbing: Jest mocks for dependencies. External API Facades are mocked when testing services that use them. Facades themselves are tested by mocking the underlying HTTP client or library's network calls.
- AI Agent Responsibility: Generate unit tests covering logic paths, props, events, edge cases, error conditions for new/modified code.
- Integration Tests:
- Scope: Interactions between components/services (e.g., API route -> service -> DB).
- Location:
tests/integration/. - Environment: Local Supabase dev environment. Consider
mswfor mocking HTTP services called by frontend/backend. - AI Agent Responsibility: Generate tests for key service interactions or API contracts.
- End-to-End (E2E) Tests:
- Scope: Validate complete user flows via UI.
- Tool: Playwright. Location:
tests/e2e/. - Key Scenarios (MVP): View newsletter list, view detail, play podcast, download newsletter.
- AI Agent Responsibility: Generate E2E test stubs/scripts for critical paths.
- Test Coverage:
- Target: Aim for 80% unit test coverage for new business logic and critical components. Quality over quantity.
- Measurement: Jest coverage reports.
- Mocking/Stubbing Strategy (General): Test one unit at a time. Mock external dependencies for unit tests. For facade unit tests: use the real library but mock its external calls at the library's boundary.
- Test Data Management: Inline mock data for unit tests. Factories/fixtures or
seed.sqlfor integration/E2E tests.
Security Best Practices
- Input Sanitization/Validation: Zod for all external inputs (API requests, function payloads, external API responses). Validate at component boundaries.
- Output Encoding: Rely on React JSX auto-escaping for frontend. Ensure HTML for newsletters is sanitized if dynamic data is injected outside of a secure templating engine.
- Secrets Management: Via environment variables (Vercel UI,
.env.local). Never hardcode or log secrets. Access viaprocess.env. Use Supabase service role key only in backend functions. - Dependency Security: Regular
npm audit. Vet new dependencies. - Authentication/Authorization:
- Workflow Trigger/Status APIs: API Key (
X-API-KEY). - Play.ht Webhook: Shared secret or signature verification.
- Supabase RLS: Enable on tables, define policies (especially for
subscribersand any data directly queried by frontend).
- Workflow Trigger/Status APIs: API Key (
- Principle of Least Privilege: Scope API keys and database roles narrowly.
- API Security (General): HTTPS (Vercel default). Consider rate limiting for public APIs. Standard HTTP security headers.
- Error Handling & Information Disclosure: Log detailed errors server-side; return generic messages/error IDs to clients.
- Regular Security Audits/Testing (Post-MVP): Consider for future enhancements.