Files
BMAD-METHOD/BETA-V3/v3-demos/full-stack-app-demo/10-sharded-docs/operational-guidelines.md

123 lines
10 KiB
Markdown

# 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 `Error` objects (or custom extensions of `Error`) 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_runs` table with an error status/message (via `WorkflowTrackerService`), 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.
- **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.
```typescript
// 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), `service` or `functionName`, a clear `message`, and relevant `details` (sanitized). **Sensitive data must NEVER be logged.** Pass error objects directly to Pino: `logger.error({ err: errorInstance, workflowRunId }, "Operation failed");`.
- **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.
- **Internal Errors / Business Logic Exceptions (Supabase Functions):**
- Use `try...catch`. Critical errors preventing task completion for a `workflow_run_id` must: 1. Log detailed error (Pino). 2. Call `WorkflowTrackerService.failWorkflow(...)`.
- Next.js API routes return generic JSON errors (e.g., `{"error": "Internal server error"}`) and appropriate HTTP status codes.
- **Database Operations (Supabase):** Critical errors treated as internal errors (log, update `workflow_runs` to '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 in `workflow_runs.details`. Systemic failures lead to `workflow_runs.status = 'failed'`.
- **`CheckWorkflowCompletionService`:** Must be resilient. Errors processing one `workflow_run_id` should be logged but not prevent processing of other runs or subsequent scheduled invocations.
### Coding Standards
These standards are mandatory for all code generation by AI agents and human developers.
- **Primary Language & Runtime:** TypeScript `5.7.2`, Node.js `22.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`)
- **File Structure:** Adhere to "Project Structure." Unit tests (`*.test.ts(x)`/`*.spec.ts(x)`) co-located with source files.
- **Asynchronous Operations:** Always use `async`/`await` for Promises; ensure proper handling.
- **Type Safety (TypeScript):** Adhere to `tsconfig.json` (`"strict": true`). Avoid `any`; use `unknown` with type narrowing. Shared types in `shared/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. Resolve `latest` tags to specific versions upon setup.
- **Environment Variables:** Manage via environment variables (`.env.example` provided). 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. Ensure `Promise` rejections are `Error` objects.
- **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")`), especially `workflowRunId`.
- **Next.js Conventions:** Follow App Router conventions. Use Server Components for data fetching where appropriate. Route Handlers for API endpoints.
- **Supabase Function Conventions:** `index.ts` as 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 `msw` for 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.sql` for 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 via `process.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 `subscribers` and any data directly queried by frontend).
- **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.