Frontend Logging
Plan Metadata
- Plan type:
sub-plan - Parent plan:
logging.md - Depends on:
N/A - Status:
documentation
Status semantics: - draft: Plan is being created or updated and is not final. - approved: Plan is approved but not yet applied in code. - documentation: Code currently exists and matches the plan contract.
Update rule: - When an existing plan is edited, set status to draft until re-approved.
System Intent
- What is being built: A frontend logging contract for React Native/Expo that standardizes log payload shape and centralizes logging through shared utilities.
- Primary consumer(s): Mobile app components, shared frontend utility code, and debugging workflows.
- Boundary (black-box scope only): Frontend logging API (
useLogging, function logger, andLoggingContextProvider) and emitted log event contract fromlogging.md. - Context placement:
LoggingContextProvidercan be mounted at any feature boundary and nested by flow (for exampleconversationandupload-memory). - Signal rule: prefer step-start/transition/error logs and avoid explicit success logs.
Stage Gate Tracker
- [x] Stage 1 Mermaid approved
- [x] Stage 2 I/O contracts approved
- [x] Stage 3 pseudocode/technical details approved or skipped
1. Mermaid Diagram
Reference: .agent/skills/create-mermaid-diagram/SKILL.md
flowchart TD
FeatureBoundary[Feature Boundary - any React subtree] -->|provides flow scope| LoggingProvider[Logging Context Provider - main/app/lib/logging/frontend-logger.tsx]
LoggingProvider -->|provides default flow| UseLoggingHook[useLogging Hook - main/app/lib/logging/frontend-logger.tsx]
FrontendFactory[Function Logger Factory - createLogger in main/app/lib/logging/frontend-logger.tsx]
LoggingProvider -->|catches render errors and emits error logs| ErrorBoundary[Logging Error Boundary - main/app/lib/logging/frontend-logger.tsx]
UseLoggingHook -->|returns logger function| FeatureCode[Feature Components and Hooks - main/app/components]
FrontendFactory -->|returns callable logger for non-react frontend code| UtilityCode[Frontend Utility Code - main/app/lib]
FeatureCode -->|log event payload| ConsoleOut[Console Output - runtime console.log]
UtilityCode -->|log event payload| ConsoleOut
ErrorBoundary -->|error payload with stack| ConsoleErr[Console Error Output - runtime console.error]
classDef unchanged fill:#d3d3d3,stroke:#666,stroke-width:1px;
classDef updated fill:#ffe58a,stroke:#666,stroke-width:1px;
classDef deleted fill:#f4a6a6,stroke:#666,stroke-width:1px;
classDef created fill:#a8e6a3,stroke:#666,stroke-width:1px;
class FeatureBoundary unchanged;
class LoggingProvider,UseLoggingHook,FrontendFactory,ErrorBoundary unchanged;
class FeatureCode,UtilityCode,ConsoleOut,ConsoleErr unchanged; 2. Black-Box Inputs and Outputs
Keep this short. Define types in JSON-style blocks and capture each flow with path-level rows. - Flow naming rule: each flow uses this format: - ### Flow: `<flowname>` - - Test files: <path/to/test_file.ext>, ... (or N/A when no automated test is required) - - Core files: <path/to/core_file.ext>, ... - N/A means explicit no-test-required waiver for that flow (not a missing mapping).
Global Types
Define shared types used across multiple flows.
FrontendLoggerInput {
step: string (required step label)
additional?: unknown (optional structured context)
}
FrontendLogEvent {
flow: string (resolved from provider context or "unknown-flow")
step: string
additional?: unknown
timestamp: string (ISO8601)
}
LoggingProviderInput {
flow: string (default flow for descendant hooks)
}
Flow: frontendUseLogging
- Test files:
main/app/__tests__/frontend-logger.test.tsx - Core files:
main/app/lib/logging/frontend-logger.tsx
Type Definitions
FrontendUseLoggingInput {
provider_flow?: string
logger_input: FrontendLoggerInput
}
FrontendUseLoggingOutput {
emitted_event: FrontendLogEvent
}
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
|---|---|---|---|---|---|
frontend-use-logging.provider-flow | FrontendUseLoggingInput provider_flow set | FrontendUseLoggingOutput emitted_event.flow=provider_flow | happy path | useLogging resolves flow from nearest provider | |
frontend-use-logging.unknown-flow-fallback | FrontendUseLoggingInput provider_flow omitted | FrontendUseLoggingOutput emitted_event.flow="unknown-flow" | subpath | fallback flow is used when no provider wraps the hook | |
frontend-use-logging.step-propagation | FrontendUseLoggingInput logger_input.step | FrontendUseLoggingOutput emitted_event.step=logger_input.step | happy path | step is forwarded unchanged |
Flow: frontendProviderErrorCapture
- Test files:
main/app/__tests__/frontend-logger.test.tsx - Core files:
main/app/lib/logging/frontend-logger.tsx
Type Definitions
FrontendProviderErrorInput {
provider: LoggingProviderInput
thrown_error: Error
component_stack: string
}
FrontendProviderErrorOutput {
emitted_error_event: FrontendLogEvent
emitted_error_event.step: "error-boundary"
emitted_error_event.additional.stack: string
emitted_error_event.additional.componentStack: string
}
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
|---|---|---|---|---|---|
frontend-provider-error-capture.render-error | FrontendProviderErrorInput | FrontendProviderErrorOutput emitted via console.error | happy path | provider catches render errors and logs stack context |
Flow: frontendFunctionLogger
- Test files:
main/app/__tests__/frontend-logger.test.tsx - Core files:
main/app/lib/logging/frontend-logger.tsx
Type Definitions
FrontendFunctionLoggerInput {
create_flow: string
logger_input: FrontendLoggerInput
}
FrontendFunctionLoggerOutput {
emitted_event: FrontendLogEvent
}
Paths
| path-name | input | output/expected state change | path-type | notes | updated |
|---|---|---|---|---|---|
frontend-function-logger.emit | FrontendFunctionLoggerInput | FrontendFunctionLoggerOutput emitted_event.flow=create_flow | happy path | non-react code gets same logging contract without hooks |
3. Pseudocode / Technical Details for Critical Flows (Optional)
Not needed...
4. Handoff to Related Plan Reconciliation
After all stages are approved, apply .agent/skills/reconcile-plans/SKILL.md to propagate contract updates across linked plans.